10.6.3 XML文件读写
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
XML(EXtensible Markup Language):可扩展标记语言目前被广泛的运用,本节讨论如何操作Xml文件。关于Xml语法结构,本书不作介绍,请自行查找相关资料。
本书使用到的Xml文件名为books.xml,具体内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<BookStore>
<Book ISBN="9787302424260">
<TITLE>星球大战:幽灵的威胁</TITLE>
<PRICE>48.00</PRICE>
<YEAR>1985</YEAR>
</Book>
<Book ISBN="9787302425274">
<TITLE>星球大战:克隆人的进攻</TITLE>
<PRICE>48.00</PRICE>
<YEAR>1985</YEAR>
</Book>
<Book ISBN="9787302426899">
<TITLE>星球大战:西斯的复仇</TITLE>
<PRICE>58.00</PRICE>
<YEAR>1985</YEAR>
</Book>
<Book ISBN="9787302421146">
<TITLE>星球大战:新的希望</TITLE>
<PRICE>35.00</PRICE>
<YEAR>1985</YEAR>
</Book>
<Book ISBN="9787302421122">
<TITLE>星球大战:帝国反击战</TITLE>
<PRICE>35.00</PRICE>
<YEAR>1985</YEAR>
</Book>
<Book ISBN="9787302421108">
<TITLE>星球大战:绝地归来</TITLE>
<PRICE>35.00</PRICE>
<YEAR>1985</YEAR>
</Book>
<Book ISBN="9787562849896">
<TITLE>星球大战:原力觉醒</TITLE>
<PRICE>48.00</PRICE>
<YEAR>2016</YEAR>
</Book>
</BookStore>
10.6.3.1 XmlDocument 类
XmlDocument类表示XML文档,可使用此类在文档中加载、验证、编辑、添加和放置 XML。
XmlDocument常用属性:
- DocumentElement:获取文档的根 XmlElement。
XmlDocument常用方法:
- CreateElement:创建元素。
- CreateXmlDeclaration:创建一个具有指定值的XmlDeclaration节点。
- Load:从指定的文件、流或者字符串加载 XML 文档。
- LoadXml:从指定的字符串加载 XML 文档。
- SelectNodes:选择匹配 XPath 表达式的节点列表。
- SelectSingleNode:选择匹配 XPath 表达式的第一个 XmlNode。
- Save:将 XML 文档保存到指定的文件、流或者字符串。如果保存为文件且已经存在,则此方法会覆盖它。
10.6.3.2 XmlNode类
XmlNode类表示XML文档中的单个节点。
XmlNode常用属性:
- Attributes:获取一个 XmlAttributeCollection,它包含该节点的特性。
- ChildNodes:获取节点的所有子节点。
- FirstChild:获取节点的第一个子级。
- HasChildNodes:获取一个值,该值指示此节点是否有任何子节点。
- InnerText:获取或设置节点及其所有子节点的串连值。
- InnerXml:获取或设置仅表示该节点的子节点的标记。
- IsReadOnly:获取指示节点是否只读的值。
- LastChild:获取节点的最后一个子级。
- NodeType:获取当前节点的类型,XmlNodeType 枚举值之一。
- OuterXml:获取包含此节点及其所有子节点的标记。
- OwnerDocument:获取该节点所属的 XmlDocument。
- ParentNode:获取该节点的父级(针对可以拥有父级的节点)。
- Value:获取或设置节点的值。
XmlNode常用方法:
- AppendChild:将指定的节点添加到该节点的子节点列表的末尾。
- RemoveAll:移除当前节点的所有子节点和/或属性。
- RemoveChild:移除指定的子节点。
- ReplaceChild:用 newChild 节点替换子节点 oldChild。
- SelectSingleNode:选择匹配 XPath 表达式的第一个 XmlNode。
- InsertAfter:将指定的节点紧接着插入指定的引用节点之后。
- InsertBefore:将指定的节点紧接着插入指定的引用节点之前。
注意:InnerText、InnerXml、OuterXml所包含的内容不同。以books.xml中
<Book ISBN="9787302426899">
<TITLE>星球大战:西斯的复仇</TITLE>
<PRICE>58.00</PRICE>
<YEAR>1985</YEAR>
</Book>
这段数据为例:
InnerText的内容仅节点内的文本,不包含属性:
星球大战:西斯的复仇58.001985
InnerXml的内容包括节点内所有的内容,但不包含节点本身:
<TITLE>星球大战:西斯的复仇</TITLE><PRICE>58.00</PRICE><YEAR>1985</YEAR>
OuterXml的内容包括节点所有内容:
<Book ISBN="9787302426899"><TITLE>星球大战:西斯的复仇</TITLE><PRICE>58.00</PRICE><YEAR>1985</YEAR></Book>
在实际编程时,请根据需要选择使用。
10.6.3.3 XmlElement类
XmlElement类表示一个元素。XmlElement类继承于XmlNode类,它的属性和方法基本都相同,这里不再累述。
10.6.3.4 Xpath
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集,由于Xpath涉及内容较多,且XPath不是本书讨论的内容,请读者自行参阅相关资料。
10.6.3.5 XML文件的读写示例
【例 10.25】【项目:code10-025】XML文件的读写。
本示例中需要用到XmlDocument、XmlNode和XmlElement这三个类。它们都在Xml命名空间下,为简化代码,请在所有代码前面加上:
using System.Xml;
窗体设计如下:
图10-14 XML文件读写窗体设计
具体代码如下:
//需要处理的XML文件
string xmlFile = "c:\\lessons\\books.xml";
//声明XmlDocument
XmlDocument xmlDoc;
'载入XML文件
//载入XML文件
private void btnLoadXml_Click(object sender, EventArgs e)
{
xmlDoc = new XmlDocument();
//载入XML文档
xmlDoc.Load(xmlFile);
//或者使用以下方法从流中载入XML文档
//System.IO.StreamReader myreader = new System.IO.StreamReader(xmlFile);
//string mystring = myreader.ReadToEnd();
//xmlDoc.LoadXml(mystring);
//myreader.Close();
//在ListView中显示XML文档数据
showXML();
}
获得XML中数据的步骤:
1、通过xmlDoc.DocumentElement 获得文档的根元素,也就是BookStore;
2、通过rootElement.ChildNodes获得根元素下的所有子节点,也就是所有的Book节点,这是一个XmlNodeList类;
3、通过for 循环来获得每个Book节点;
4、通过 xmlchild.Attributes("ISBN").Value 获得Book 节点的 ISBN 属性;
5、通过再次的for循环,枚举Book节点下的子节点,并用xmlgrandchild.InnerText获得相应的值。
//在ListView中显示XML文档数据
private void showXML()
{
lvBookInfo.Items.Clear();
//声明XmlElement
XmlElement rootElement;
//设置为文档的根 XmlElement
rootElement = xmlDoc.DocumentElement;
//获得根元素下的所有子节点
XmlNodeList xmlNl = rootElement.ChildNodes;
ListViewItem lvItem;
foreach(XmlNode xmlchild in xmlNl)
{
//节点的ISBN属性的值
lvItem = new ListViewItem(xmlchild.Attributes["ISBN"].Value);
//将该节点下的所有子节点的文本添加到ListView中
foreach(XmlNode xmlgrandchild in xmlchild.ChildNodes)
lvItem.SubItems.Add(xmlgrandchild.InnerText);
lvBookInfo.Items.Add(lvItem);
}
}
//当选中ListView中某项时,在旁边显示对应信息
private void lvBookInfo_SelectedIndexChanged(object sender, EventArgs e)
{
if (lvBookInfo.SelectedItems.Count < 1)
return;
ListViewItem lvItem;
lvItem = lvBookInfo.SelectedItems[0];
if (lvItem == null)
return;
txtISBN.Text = lvItem.Text;
txtName.Text = lvItem.SubItems[1].Text;
txtPrice.Text = lvItem.SubItems[2].Text;
txtDate.Text = lvItem.SubItems[3].Text;
}
向XML中添加数据的步骤:
1、通过xmlDoc.DocumentElement 获得文档的根元素,也就是BookStore;
2、定义一个xml元素xmlNewBook,并使xmlNewBook为xmlDoc创建的Book元素:xmlDoc.CreateElement("Book")
3、设置属性:xmlNewBook.SetAttribute("ISBN", txtISBN.Text)
4、将元素添加到根节点下:rootElement.AppendChild(xmlNewBook)
注意:xml元素也是xml的节点,在.net中,XmlElement继承于XmlNode
5、使用同样方法,在xmlDoc中创建元素,并添加到xmlNewBook元素下。
//向XML中添加新的数据
private void btnAdd_Click(object sender, EventArgs e)
{
//声明XmlElement
XmlElement rootElement;
//设置为文档的根XmlElement
rootElement = xmlDoc.DocumentElement;
//声明Book元素
XmlElement xmlNewBook;
xmlNewBook = xmlDoc.CreateElement("Book");
xmlNewBook.SetAttribute("ISBN", txtISBN.Text);
//将Book元素加入根元素
rootElement.AppendChild(xmlNewBook);
//声明TITLE元素
XmlElement xmlNewEle ;
xmlNewEle = xmlDoc.CreateElement("TITLE");
xmlNewEle.InnerText = txtName.Text;
//将TITLE元素加入Book元素下
xmlNewBook.AppendChild(xmlNewEle);
//声明PRICE元素
xmlNewEle = xmlDoc.CreateElement("PRICE");
xmlNewEle.InnerText = txtPrice.Text;
//将TITLE元素加入Book元素下
xmlNewBook.AppendChild(xmlNewEle);
//声明YEAR元素
xmlNewEle = xmlDoc.CreateElement("YEAR");
xmlNewEle.InnerText = txtDate.Text;
//将TITLE元素加入Book元素下
xmlNewBook.AppendChild(xmlNewEle);
showXML();
}
修改XML中数据的步骤:
1、通过xmlDoc.DocumentElement 获得文档的根元素,也就是BookStore;
2、使用SelectSingleNode(XPath字符串)获得根元素符合条件的第一个节点,需要注意的是,如果XPath有多个相同结果,那么会选中第一个。
在本例中,代码中变量condition是XPath表达式,它的值是:
"/BookStore/Book[@ISBN=\"" + isbn + "\"]"
3、修改节点值以及其子节点中的文本。
表示需要查询BookStore节点下的Book节点,且该Book节点属性ISBN为isbn。
//编辑当前选中的XML节点的信息
private void btnEdit_Click(object sender, EventArgs e)
{
if (lvBookInfo.SelectedItems.Count < 1)
return;
ListViewItem lvItem;
lvItem = lvBookInfo.SelectedItems[0];
if (lvItem == null)
return;
//声明XmlElement
XmlElement rootElement;
//设置为文档的根 XmlElement
rootElement = xmlDoc.DocumentElement;
string isbn = lvItem.Text;
//定义一个XPath表达式
string condition = "/BookStore/Book[@ISBN=\"" + isbn + "\"]";
//获得匹配 XPath 表达式的第一个 XmlNode
XmlNode xmlNd = xmlDoc.SelectSingleNode(condition);
//修改节点相应的值
xmlNd.Attributes["ISBN"].Value = txtISBN.Text;
xmlNd.ChildNodes[0].InnerText = txtName.Text;
xmlNd.ChildNodes[1].InnerText = txtPrice.Text;
xmlNd.ChildNodes[2].InnerText = txtDate.Text;
showXML();
}
删除XML中数据的步骤:
1、通过xmlDoc.DocumentElement 获得文档的根元素,也就是BookStore;
2、使用SelectSingleNode(XPath字符串)获得根元素符合条件的第一个节点;
3、从根元素中移除节点。
//从XML中删除数据
private void btnDel_Click(object sender, EventArgs e)
{
if (lvBookInfo.SelectedItems.Count < 1)
return;
ListViewItem lvItem;
lvItem = lvBookInfo.SelectedItems[0];
if (lvItem == null)
return;
//声明XmlElement
XmlElement rootElement;
//设置为文档的根XmlElement
rootElement = xmlDoc.DocumentElement;
string isbn = lvItem.Text;
//定义一个XPath字符串
string condition = "/BookStore/Book[@ISBN=\"" + isbn + "\"]";
//获得匹配 XPath 表达式的第一个 XmlNode
XmlNode xmlNd = xmlDoc.SelectSingleNode(condition);
rootElement.RemoveChild(xmlNd);
//如果使用以下代码将会保留该节点,而把节点内的数据删除,即:
//保留内容为:< Book > </ Book >
//xmlNd.RemoveAll();
showXML();
}
最后,不管增加、删除还是修改,都别忘了保存数据。
//保存XML数据
private void btnSave_Click(object sender, EventArgs e)
{
xmlDoc.Save(xmlFile);
}
运行结果如下图所示:
图10-15 books.xml文件读写
【例 10.26】【项目:code10-026】XML文件的创建。
【例 10.25】是使用的已经存在的XML文件进行操作。如果需要创建一个新的Xml文件,可以使用以下方法:
1、直接写xml结构的字符串:
private void Button1_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
string[] strXmlDefault = new string[3];
strXmlDefault[0] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
strXmlDefault[1] = "<BookStore>";
strXmlDefault[2] = "</BookStore>";
string strXml = String.Join("", strXmlDefault);
xmlDoc.LoadXml(strXml);
}
2、声明一个XmlDeclaration并把它添加进XmlDocument中,然后添加根元素
private void Button2_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
XmlDeclaration XmlDec;
XmlDec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "");
xmlDoc.AppendChild(XmlDec);
XmlElement xmlRoot;
xmlRoot = xmlDoc.CreateElement("BookStore");
xmlDoc.AppendChild(xmlRoot);
}
需要注意的是,第二种方法虽然创建了XML文档,但是BookStore节点下并没有数据,文档中节点是<BookStore/>,而不是<BookStore></BookStore>,但使用时实际是一样的。
创建好XmlDocument后就可以执行增加数据、保存XML文档到文件等操作了,具体参看【例 10.25】。
学习更多vb.net知识,请参看vb.net 教程 目录
学习更多C#知识,请参看C#教程 目录