该系统数据量不大,正常情况下不到十条记录,再加上一些用户的配置,所以用XML文件来存储信息比较方便,以后也可能不会放到数据库中,所以在设计数据访问时没有什么设计,只是提供一些增删改的方法。
在解决方案LibraryHelper中添加工程DAL,添加一个类BookXML,对保存图书信息的XML文件的操作。把命名空间改为Libraryhelper.DAL,引入上一小节建好的Model工程。
创建名为BookXML.xml的XML文件用来保存从图书馆网站上读取下来的数据,结构如下:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
<?xml version="1.0" standalone="yes"?>
<Books>
<book>
<title>重构:改善既有代码的设计</title>
<borrowDate>2008-12-21</borrowDate>
<returnDate>2009-03-23</returnDate>
<borrowNum>0 续借 </borrowNum>
<isbnNum>TP311.11/31</isbnNum>
</book>
<book>
<title>框架设计:CLR VIA C#</title>
<borrowDate>2008-12-21</borrowDate>
<returnDate>2009-03-23</returnDate>
<borrowNum>0 续借 </borrowNum>
<isbnNum>TP312C/330</isbnNum>
</book>
</Books>
分别保存了书名,外借时间,应还时间,续借次数,图书ISBN编号等信息。把该文件放到本工程的\bin\Debug目录下,读取时不用写路径,而且项目打包时比较方便,整个项目就放在一个文件夹里。
现在来写BookXML类中的方法,该类中有一个对象是用来对XML文件的操作的,可以用DataSet,但是这种做法用一个不好,就是当文件中没有记录时就出错,必须要保持至少有一条记录,如下:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
1
DataSet bookDataSet;
2
public BookXML()
3![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
4
bookDataSet = new DataSet();
5
bookDataSet.ReadXml("BookXML.xml");
6
}
7![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
8
//取得所有对象
9
public List<Book> GetBookList()
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
11
List<Book> bookList = new List<Book>();
12
Int32 bookNum = bookDataSet.Tables["book"].Rows.Count;
13
for (Int32 i = 0; i < bookNum; i++)
14![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
15
//![](https://www.cnblogs.com/Images/dot.gif)
16
}
17
//![](https://www.cnblogs.com/Images/dot.gif)
18
}
19![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
如上代码当没有记录时到第12行就出错,因为当XML文件中没有记录时是这样的:
<?xml version="1.0" standalone="yes"?>
<Books>
</Books>
没有book标签,所以它还对book的引用就出错,所以采用DOM解析,这种方法操作XML文件很方便,如下,我们写了一些增删改方法:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Data;
5
using System.Collections;
6
using System.Xml;
7![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
8
using LibraryHelper.Model;
9![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
10![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
11
namespace LibraryHelper.DAL
12![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
13
public class BookXML
14![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
15
XmlDocument xmlDoc;
16
XmlNode xmlNode;
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
public BookXML()
19![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
20
xmlDoc = new XmlDocument();
21
xmlDoc.Load("BookXML.xml"); //加载XML文件
22
xmlNode = xmlDoc.SelectSingleNode("Books");
23
}
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
//添加
26
public Boolean InsertBook(Book insertBook)
27![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28
try
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
30
XmlElement xmlNodeBook = xmlDoc.CreateElement("book"); //创建一个标签
31![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32
XmlElement xmlNodeTitle = xmlDoc.CreateElement("title");//创建一个标签
33
xmlNodeTitle.InnerText = insertBook.Title;//设置标签的值
34
xmlNodeBook.AppendChild(xmlNodeTitle);//把该标签加到它的父标签中
35![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
XmlElement xmlNodeBorrowDate = xmlDoc.CreateElement("borrowDate");//同上
37
xmlNodeBorrowDate.InnerText = insertBook.BorrowDate.ToShortDateString();
38
xmlNodeBook.AppendChild(xmlNodeBorrowDate);
39![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
40
XmlElement xmlNodeReturnDate = xmlDoc.CreateElement("returnDate");
41
xmlNodeReturnDate.InnerText = insertBook.ReturnDate.ToShortDateString();
42
xmlNodeBook.AppendChild(xmlNodeReturnDate);
43![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
44
XmlElement xmlNodeBorrowNum = xmlDoc.CreateElement("borrowNum");
45
xmlNodeBorrowNum.InnerText = insertBook.BorrowNum;
46
xmlNodeBook.AppendChild(xmlNodeBorrowNum);
47![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
48
XmlElement xmlNodeIsbn = xmlDoc.CreateElement("isbn");
49
xmlNodeIsbn.InnerText = insertBook.ISBN;
50
xmlNodeBook.AppendChild(xmlNodeIsbn);
51
52
xmlNode.AppendChild(xmlNodeBook);
53![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
54
xmlDoc.Save("BookXML.xml");
55![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
56
return true;
57
}
58
catch (Exception ex)
59![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
60
throw ex;
61
}
62
}
63![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
64
//取得所有对象
65
public List<Book> GetBookList()
66![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
67
List<Book> bookList = new List<Book>();
68
for (Int32 i = 0; i < xmlNode.ChildNodes.Count; i++)
69![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
70
Book book = new Book();
71
book.Title = xmlNode.ChildNodes[i].ChildNodes[0].InnerText;
72
book.BorrowDate = Convert.ToDateTime(xmlNode.ChildNodes[i].ChildNodes[1].InnerText);
73
book.ReturnDate = Convert.ToDateTime(xmlNode.ChildNodes[i].ChildNodes[2].InnerText);
74
book.BorrowNum = xmlNode.ChildNodes[i].ChildNodes[3].InnerText;
75
book.ISBN = xmlNode.ChildNodes[i].ChildNodes[4].InnerText;
76
bookList.Add(book);
77
}
78
return bookList;
79
}
80![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
81
//取得记录数量
82
public Int32 GetBookNum()
83![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
84
return xmlNode.ChildNodes.Count;
85
}
86![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
87
//取得一条记录
88
public Book GetSingleBookByRowIndex(Int32 rowIndex)
89![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
90
Book book = new Book();
91
book.Title = xmlNode.ChildNodes[rowIndex].ChildNodes[0].InnerText;
92
book.BorrowDate = Convert.ToDateTime(xmlNode.ChildNodes[rowIndex].ChildNodes[1].InnerText);
93
book.ReturnDate = Convert.ToDateTime(xmlNode.ChildNodes[rowIndex].ChildNodes[2].InnerText);
94
book.BorrowNum = xmlNode.ChildNodes[rowIndex].ChildNodes[3].InnerText;
95
book.ISBN = xmlNode.ChildNodes[rowIndex].ChildNodes[4].InnerText;
96
return book;
97
}
98![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
99
//删除一条记录
100
public Boolean DeleteBookByRowIndex(Int32 rowIndex)
101![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
102
try
103![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
104
xmlNode.RemoveChild(xmlNode.ChildNodes[rowIndex]);
105
xmlDoc.Save("BookXML.xml");
106
return true;
107
}
108
catch (Exception ex)
109![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
110
throw ex;
111
}
112
}
113![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
114
//删除所有记录
115
public Boolean DeleteAllBook()
116![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
117
try
118![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
119
xmlNode.RemoveAll();
120
xmlDoc.Save("BookXML.xml");
121
return true;
122
}
123
catch (Exception ex)
124![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
125
throw ex;
126
}
127
}
128![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
129
//修改
130
public Boolean UpdataBookByRowIndex(Int32 rowIndex,Book updateBook)
131![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
132
try
133![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
134
XmlNode updateNode = xmlNode.ChildNodes[rowIndex];
135
updateNode.ChildNodes[0].InnerText = updateBook.Title;
136
updateNode.ChildNodes[1].InnerText = updateBook.BorrowDate.ToShortDateString();
137
updateNode.ChildNodes[2].InnerText = updateBook.ReturnDate.ToShortDateString();
138
updateNode.ChildNodes[3].InnerText = updateBook.BorrowNum;
139
updateNode.ChildNodes[4].InnerText = updateBook.ISBN;
140![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
141
xmlDoc.Save("BookXML.xml");
142![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
143
return true;
144
}
145
catch (Exception ex)
146![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
147
throw ex;
148
}
149
}
150
}
151
}
152![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
我们再建一个UserXML的类,把它的命名空间也改成LibraryHelper.DAL,再建一个UserXML.xml的文件,保存用户登录到图书馆的账号和密码,一样放到bin\Debug目录下,在UserXML类里也写了些简单的方法对UserXML.xml文件的操作,如下:
UserXML.xml:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<LoginName>20050632540</LoginName>
<Password>850313</Password>
</User>
</Users>
UserXML类:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Xml;
5
using LibraryHelper.Model;
6![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
7
namespace LibraryHelper.DAL
8![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
9
public class UserXML
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
XmlDocument xmlDoc;
12
XmlNode xmlNode;
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
public UserXML()
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
xmlDoc = new XmlDocument();
17
xmlDoc.Load("UserXML.xml"); //加载
18
xmlNode = xmlDoc.SelectSingleNode("Users");
19
}
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
//取得User
22
public User GetUser()
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
User user = new User();
25
user.LoginID = xmlNode.ChildNodes[0].ChildNodes[0].InnerText;
26
user.Password = xmlNode.ChildNodes[0].ChildNodes[1].InnerText;
27
return user;
28
}
29
30
//保存
31
public Boolean SaveUser(User user)
32![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
33
try
34![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
35
xmlNode.ChildNodes[0].ChildNodes[0].InnerText = user.LoginID;
36
xmlNode.ChildNodes[0].ChildNodes[1].InnerText = user.Password;
37
xmlDoc.Save("UserXML.xml");
38
return true;
39
}
40
catch (Exception ex)
41![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
42
throw ex;
43
}
44
}
45
46
}
47
}
48![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
依次再加一个对宽带连接账号信息的xml文件和对该文件操作的类如下:
ADSLXML.xml:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
<?xml version="1.0" encoding="utf-8"?>
<ADSL>
<ConnectionName>宽带</ConnectionName>
<UserName>user@xyw</UserName>
<UserPassword>user</UserPassword>
</ADSL>
对该文件操作的类UserXML:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Xml;
5![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
namespace LibraryHelper.DAL
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
8
public class ADSLXML
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
XmlDocument xmlDoc;
11
XmlNode xmlNode;
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
public ADSLXML()
14![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
15
xmlDoc = new XmlDocument();
16
xmlDoc.Load("ADSLXML.xml"); //加载
17
xmlNode = xmlDoc.SelectSingleNode("ADSL");
18
}
19![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
//返回用户指定的宽带连接名
21
public String GetConnectionName()
22![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
23
return xmlNode.ChildNodes[0].InnerText;
24
}
25![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26
//返回用户名
27
public String GetUserName()
28![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
29
return xmlNode.ChildNodes[1].InnerText;
30
}
31![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32
//返回密码
33
public String GetUserPassword()
34![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
35
return xmlNode.ChildNodes[2].InnerText;
36
}
37![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
38
//保存
39
public Boolean SaveADSL(String connectionName, String userName, String userPassword)
40![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41
try
42![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
43
xmlNode.ChildNodes[0].InnerText = connectionName;
44
xmlNode.ChildNodes[1].InnerText = userName;
45
xmlNode.ChildNodes[2].InnerText = userPassword;
46
xmlDoc.Save("ADSLXML.xml");
47
return true;
48
}
49
catch (Exception ex)
50![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
51
throw ex;
52
}
53
}
54
}
55
}
56![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
同样再那一个xml文件用来保存用户的一些配置信息和对该文件操作的类如下:
SettingXML.xml:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
<?xml version="1.0" encoding="utf-8"?>
<Setting>
<warningDay>100</warningDay>
<startType>0</startType>
<lastStartTime>2009-3-6</lastStartTime>
<disConnectionADSL>0</disConnectionADSL>
</Setting>
warningDay是说当还剩n天还书时,当n<100时该书就进入警戒范围,用户开机时就给出提示
startType是说系统每次计算机启动时都启动还是每天只启动一次,0为每次都启动,1为每天只能启动一次,所以下面lastStartTime就保存了上一次的登录时间
disConnectionADSL是说当退出该系统时是否自动断开宽带连接,0为断开,1为不断开
对该文件操作的类SettingXML中的一些方法如下:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace LibraryHelper.DAL
{
public class SettingXML
{
XmlDocument xmlDoc;
XmlNode xmlNode;
public SettingXML()
{
xmlDoc = new XmlDocument();
xmlDoc.Load("SettingXML.xml");
xmlNode = xmlDoc.SelectSingleNode("Setting");
}
//取得进入警戒时间
public String GetWarningDay()
{
return xmlNode.ChildNodes[0].InnerText;
}
//取得启动类型
public String GetStartType()
{
return xmlNode.ChildNodes[1].InnerText;
}
//取得上次启动时间
public String GetLastStartTime()
{
return xmlNode.ChildNodes[2].InnerText;
}
//取得是否断开宽带连接
public String GetDisconnectionADSL()
{
return xmlNode.ChildNodes[3].InnerText;
}
//该设置可能是分开来设置的,所以方法也分开
//设置进入警戒时间
public void SetWarningDay(String warningDay)
{
try
{
xmlNode.ChildNodes[0].InnerText = warningDay;
xmlDoc.Save("SettingXML.xml");
}
catch (Exception ex)
{
throw ex;
}
}
//设置启动类型
public void SetStartType(String startType)
{
try
{
xmlNode.ChildNodes[1].InnerText = startType;
xmlDoc.Save("SettingXML.xml");
}
catch (Exception ex)
{
throw ex;
}
}
//设置上次启动时间
public void SetLastStartTime(String lastStartTime)
{
try
{
xmlNode.ChildNodes[2].InnerText = lastStartTime;
xmlDoc.Save("SettingXML.xml");
}
catch (Exception ex)
{
throw ex;
}
}
//设置是否断开宽带连接
public Boolean SetDisconnectionADSL(String isConnection)
{
try
{
xmlNode.ChildNodes[3].InnerText = isConnection;
xmlDoc.Save("SettingXML.xml");
return true;
}
catch (Exception ex)
{
throw ex;
}
}
}
}
注意到对ADSLXML.xml和SettingXML.xml文件的操作时我们并没有封装到对象,而是用方法每个属性都分开来取,是因为这些可能在不同一个地方使用,这样单个写用得更方便.