一. XmlDocument类:
XmlDocument与XmlReader类从.NET 1.0就已经存在了。W3C定义了一个叫做文件对象模型(DOM: Document Object Model)的标准来处理XML文档。支持DOM的类可以自由地定位并修改XML文档。要想使用XmlDocument类,需要添加System.Xml.dll的引用,并且引入System.Xml命名空间。XmlDocument类使用DOM级别1与级别2,在内存中对XML进行表示。这个类可以定位寻找或者修改XML结点。
1.创建XmlDocument对象:
下面这个例子演示了如何使用XmlDocument类。
private void createAndSaveXmlDocumentToolStripMenuItem_Click( object sender, EventArgs e) { //Declare and create new XmlDocument var xmlDoc = new XmlDocument(); XmlElement el; int childCounter; int grandChildCounter; //Create the xml declaration first xmlDoc.AppendChild( xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null)); //Create the root node and append into doc el = xmlDoc.CreateElement("MyRoot"); xmlDoc.AppendChild(el); //Child Loop for (childCounter = 1; childCounter <= 4; childCounter++) { XmlElement childelmt; XmlAttribute childattr; //Create child with ID attribute childelmt = xmlDoc.CreateElement("MyChild"); childattr = xmlDoc.CreateAttribute("ID"); childattr.Value = childCounter.ToString(); childelmt.Attributes.Append(childattr); //Append element into the root element el.AppendChild(childelmt); for (grandChildCounter = 1; grandChildCounter <= 3; grandChildCounter++) { //Create grandchildren childelmt.AppendChild(xmlDoc.CreateElement("MyGrandChild")); } } //Save to file xmlDoc.Save(getFilePath("XmlDocumentTest.xml")); txtLog.AppendText("XmlDocumentTest.xml Created\r\n"); } private string getFilePath(string fileName) { return Path.Combine(Environment.GetFolderPath( Environment.SpecialFolder.Desktop), fileName); }
最后生成的XML文档如下:
<?xml version="1.0" encoding="utf-8"?> <MyRoot> <MyChild ID="1"> <MyGrandChild /> <MyGrandChild /> <MyGrandChild /> </MyChild> <MyChild ID="2"> <MyGrandChild /> <MyGrandChild /> <MyGrandChild /> </MyChild> <MyChild ID="3"> <MyGrandChild /> <MyGrandChild /> <MyGrandChild /> </MyChild> <MyChild ID="4"> <MyGrandChild /> <MyGrandChild /> <MyGrandChild /> </MyChild> </MyRoot>
2.使用DOM来解析XmlDocument对象:
XmlDocument对象可以使用递归的方法来遍历所有元素。请看下面的例子:
private void parsingAndXmlDocumentToolStripMenuItem_Click(object sender, EventArgs e) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(getFilePath("XmlDocumentTest.xml")); RecurseNodes(xmlDoc.DocumentElement); } public void RecurseNodes(XmlNode node) { var sb = new StringBuilder(); //start recursive loop with level 0 RecurseNodes(node, 0, sb); txtLog.Text = sb.ToString(); } public void RecurseNodes(XmlNode node, int level, StringBuilder sb) { sb.AppendFormat("{0,2} Type:{1,-9} Name:{2,-13} Attr:", level, node.NodeType, node.Name); foreach (XmlAttribute attr in node.Attributes) { sb.AppendFormat("{0}={1} ", attr.Name, attr.Value); } sb.AppendLine(); foreach (XmlNode n in node.ChildNodes) { RecurseNodes(n, level + 1, sb); } }
输出的结果如下:
0 Type:Element Name:MyRoot Attr 1 Type:Element Name:MyChild AttrID=1 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 1 Type:Element Name:MyChild AttrID=2 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 1 Type:Element Name:MyChild AttrID=3 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 1 Type:Element Name:MyChild AttrID=4 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr 2 Type:Element Name:MyGrandChild Attr
3.搜索XmlDocument对象:
SelectSingleNode方法可以用来定位XML元素;它需要将XPath查询传递给该方法。下面的代码演示了如何通过使用XPath查询来调用SelectSingleNode方法查询到ID为3的MyChild元素。
private void searchingAnXmlDocumentToolStripMenuItem_Click( object sender, EventArgs e) { var xmlDoc = new XmlDocument(); xmlDoc.Load(getFilePath("XmlDocumentTest.xml")); var node = xmlDoc.SelectSingleNode("//MyChild[@ID='3']"); RecurseNodes(node); }
GetElementsByTagName方法返回一个包含所有符合条件的XmlNode列表。
private void getElementsByTagNameToolStripMenuItem_Click( object sender, EventArgs e) { var xmlDoc = new XmlDocument(); xmlDoc.Load(getFilePath("XmlDocumentTest.xml")); var elmts = xmlDoc.GetElementsByTagName("MyGrandChild"); var sb = new StringBuilder(); foreach (XmlNode node in elmts) { RecurseNodes(node, 0, sb); } txtLog.Text = sb.ToString(); }
SelectNodes方法也需要使用XPath查询来返回一个XmlNode 列表。这个方法要比GetElementsByTagName更灵活,因为GetElementsByTagName局限于标签名(tag name)。
private void selectNodesToolStripMenuItem_Click( object sender, EventArgs e) { var xmlDoc = new XmlDocument(); xmlDoc.Load(getFilePath("XmlDocumentTest.xml")); var elmts = xmlDoc.SelectNodes("//MyGrandChild"); var sb = new StringBuilder(); foreach (XmlNode node in elmts) { RecurseNodes(node, 0, sb); } txtLog.Text = sb.ToString(); }
二. XmlReader类:
XmlReader是一个抽象类,用来读取和解析XML。一个更常用的子类是XmlTextReader,它可以一个结点一个结点的读取XML。XmlReader类提供最快并且占用内存最少的方法来读取和解析XML数据流,该读取只能向前,并且没有缓存。这个类适用于读取很大的XML文件,并且需要的数据在文件里靠前的位置。下面是一个使用XmlReader的例子:
private void parsingWithXmlReaderToolStripMenuItem_Click(object sender, EventArgs e) { var sb = new StringBuilder(); var xmlReader = new XmlTextReader(getFilePath("XmlDocumentTest.xml")); while (xmlReader.Read()) { switch (xmlReader.NodeType) { case XmlNodeType.XmlDeclaration: case XmlNodeType.Element: case XmlNodeType.Comment: sb.AppendFormat("{0}: {1} = {2}", xmlReader.NodeType, xmlReader.Name, xmlReader.Value); sb.AppendLine(); break; case XmlNodeType.Text: sb.AppendFormat(" - Value: {0}", xmlReader.Value); sb.AppendLine(); break; } if (xmlReader.HasAttributes) { while (xmlReader.MoveToNextAttribute()) { sb.AppendFormat(" - Attribute: {0} = {1}", xmlReader.Name, xmlReader.Value); sb.AppendLine(); } } } xmlReader.Close(); txtLog.Text = sb.ToString(); }
输出结果如下:
XmlDeclaration: xml=version="1.0" encoding="utf-8" Attribute: version=1.0 Attribute: encoding=utf-8 Element: MyRoot= Element: MyChild= Attribute: ID=1 Element: MyGrandChild= Element: MyGrandChild= Element: MyGrandChild= Element: MyChild= Attribute: ID=2 Element: MyGrandChild= Element: MyGrandChild= Element: MyGrandChild= Element: MyChild= Attribute: ID=3 Element: MyGrandChild= Element: MyGrandChild= Element: MyGrandChild= Element: MyChild= Attribute: ID=4 Element: MyGrandChild= Element: MyGrandChild= Element: MyGrandChild=
三. 小节:
•XmlDocument类读取XML结点是全部存在内存中,任意定位,并且可读也可写的。
•XmlReader类读取XML结点使用的是快速数据流(不是一次读取完将数据全部存在内存中),只能向前,只读的。
•XmlDocument类易于使用,而XmlReader类读取效率很高。
•XmlDocument类可以使用元素名来读取XML结点。
•XmlDocument类可以使用XPath来读取结点。
原文出自《Access Data with Microsoft .NET Framework 4》