XML: 使用XmlDocument 与 XmlReader 类

一. 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类。

  1. private void createAndSaveXmlDocumentToolStripMenuItem_Click(  
  2.    object sender, EventArgs e)  
  3. {  
  4.    //Declare and create new XmlDocument   
  5.    var xmlDoc = new XmlDocument();  
  6.   
  7.    XmlElement el;  
  8.    int childCounter;  
  9.    int grandChildCounter;  
  10.   
  11.    //Create the xml declaration first   
  12.    xmlDoc.AppendChild(  
  13.       xmlDoc.CreateXmlDeclaration("1.0""utf-8"null));  
  14.   
  15.    //Create the root node and append into doc   
  16.    el = xmlDoc.CreateElement("MyRoot");  
  17.    xmlDoc.AppendChild(el);  
  18.   
  19.    //Child Loop   
  20.    for (childCounter = 1; childCounter <= 4; childCounter++)  
  21.    {  
  22.       XmlElement childelmt;  
  23.       XmlAttribute childattr;  
  24.   
  25.       //Create child with ID attribute   
  26.       childelmt = xmlDoc.CreateElement("MyChild");  
  27.       childattr = xmlDoc.CreateAttribute("ID");  
  28.       childattr.Value = childCounter.ToString();  
  29.       childelmt.Attributes.Append(childattr);  
  30.   
  31.       //Append element into the root element   
  32.       el.AppendChild(childelmt);  
  33.       for (grandChildCounter = 1; grandChildCounter <= 3;  
  34.          grandChildCounter++)  
  35.       {  
  36.          //Create grandchildren    
  37.          childelmt.AppendChild(xmlDoc.CreateElement("MyGrandChild"));  
  38.       }  
  39.    }  
  40.   
  41.    //Save to file   
  42.    xmlDoc.Save(getFilePath("XmlDocumentTest.xml"));  
  43.    txtLog.AppendText("XmlDocumentTest.xml Created\r\n");  
  44.   
  45. }  
  46.   
  47. private string getFilePath(string fileName)  
  48. {  
  49.    return Path.Combine(Environment.GetFolderPath(  
  50.       Environment.SpecialFolder.Desktop), fileName);  
  51. }  
      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文档如下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <MyRoot>  
  3.   <MyChild ID="1">  
  4.     <MyGrandChild />  
  5.     <MyGrandChild />  
  6.     <MyGrandChild />  
  7.   </MyChild>  
  8.   <MyChild ID="2">  
  9.     <MyGrandChild />  
  10.     <MyGrandChild />  
  11.     <MyGrandChild />  
  12.   </MyChild>  
  13.   <MyChild ID="3">  
  14.     <MyGrandChild />  
  15.     <MyGrandChild />  
  16.     <MyGrandChild />  
  17.   </MyChild>  
  18.   <MyChild ID="4">  
  19.     <MyGrandChild />  
  20.     <MyGrandChild />  
  21.     <MyGrandChild />  
  22.   </MyChild>  
  23. </MyRoot>  
<?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对象可以使用递归的方法来遍历所有元素。请看下面的例子:

  1. private void parsingAndXmlDocumentToolStripMenuItem_Click(object sender, EventArgs e)  
  2. {  
  3.    XmlDocument xmlDoc = new XmlDocument();  
  4.    xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));  
  5.    RecurseNodes(xmlDoc.DocumentElement);  
  6. }  
  7.   
  8. public void RecurseNodes(XmlNode node)  
  9. {  
  10.    var sb = new StringBuilder();  
  11.    //start recursive loop with level 0   
  12.    RecurseNodes(node, 0, sb);  
  13.    txtLog.Text = sb.ToString();  
  14. }  
  15.   
  16. public void RecurseNodes(XmlNode node, int level, StringBuilder sb)  
  17. {  
  18.    sb.AppendFormat("{0,2} Type:{1,-9} Name:{2,-13} Attr:",  
  19.       level, node.NodeType, node.Name);  
  20.   
  21.    foreach (XmlAttribute attr in node.Attributes)  
  22.    {  
  23.       sb.AppendFormat("{0}={1} ", attr.Name, attr.Value);  
  24.    }  
  25.    sb.AppendLine();  
  26.   
  27.    foreach (XmlNode n in node.ChildNodes)  
  28.    {  
  29.       RecurseNodes(n, level + 1, sb);  
  30.    }  
  31. }  
      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);
         }
      }

输出的结果如下:

  1. 0 Type:Element   Name:MyRoot        Attr  
  2. 1 Type:Element   Name:MyChild       AttrID=1  
  3. 2 Type:Element   Name:MyGrandChild  Attr  
  4. 2 Type:Element   Name:MyGrandChild  Attr  
  5. 2 Type:Element   Name:MyGrandChild  Attr  
  6. 1 Type:Element   Name:MyChild       AttrID=2  
  7. 2 Type:Element   Name:MyGrandChild  Attr  
  8. 2 Type:Element   Name:MyGrandChild  Attr  
  9. 2 Type:Element   Name:MyGrandChild  Attr  
  10. 1 Type:Element   Name:MyChild       AttrID=3  
  11. 2 Type:Element   Name:MyGrandChild  Attr  
  12. 2 Type:Element   Name:MyGrandChild  Attr  
  13. 2 Type:Element   Name:MyGrandChild  Attr  
  14. 1 Type:Element   Name:MyChild       AttrID=4  
  15. 2 Type:Element   Name:MyGrandChild  Attr  
  16. 2 Type:Element   Name:MyGrandChild  Attr  
  17. 2 Type:Element   Name:MyGrandChild  Attr  
 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元素。

  1. private void searchingAnXmlDocumentToolStripMenuItem_Click(  
  2.    object sender, EventArgs e)  
  3. {  
  4.    var xmlDoc = new XmlDocument();  
  5.    xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));  
  6.   
  7.    var node = xmlDoc.SelectSingleNode("//MyChild[@ID='3']");  
  8.    RecurseNodes(node);  
  9. }  
      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列表。

  1. private void getElementsByTagNameToolStripMenuItem_Click(  
  2.    object sender, EventArgs e)  
  3. {  
  4.    var xmlDoc = new XmlDocument();  
  5.    xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));  
  6.   
  7.    var elmts = xmlDoc.GetElementsByTagName("MyGrandChild");  
  8.   
  9.    var sb = new StringBuilder();  
  10.    foreach (XmlNode node in elmts)  
  11.    {  
  12.       RecurseNodes(node, 0, sb);  
  13.    }  
  14.    txtLog.Text = sb.ToString();  
  15. }  
      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)。

  1. private void selectNodesToolStripMenuItem_Click(  
  2.    object sender, EventArgs e)  
  3. {  
  4.    var xmlDoc = new XmlDocument();  
  5.    xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));  
  6.   
  7.    var elmts = xmlDoc.SelectNodes("//MyGrandChild");  
  8.   
  9.    var sb = new StringBuilder();  
  10.    foreach (XmlNode node in elmts)  
  11.    {  
  12.       RecurseNodes(node, 0, sb);  
  13.    }  
  14.    txtLog.Text = sb.ToString();  
  15. }  
      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的例子:

  1. private void parsingWithXmlReaderToolStripMenuItem_Click(object sender, EventArgs e)  
  2. {  
  3.    var sb = new StringBuilder();  
  4.    var xmlReader = new XmlTextReader(getFilePath("XmlDocumentTest.xml"));  
  5.   
  6.    while (xmlReader.Read())  
  7.    {  
  8.       switch (xmlReader.NodeType)  
  9.       {  
  10.          case XmlNodeType.XmlDeclaration:  
  11.          case XmlNodeType.Element:  
  12.          case XmlNodeType.Comment:  
  13.             sb.AppendFormat("{0}: {1} = {2}",  
  14.                               xmlReader.NodeType,  
  15.                               xmlReader.Name,  
  16.                               xmlReader.Value);  
  17.             sb.AppendLine();  
  18.             break;  
  19.          case XmlNodeType.Text:  
  20.             sb.AppendFormat(" - Value: {0}", xmlReader.Value);  
  21.             sb.AppendLine();  
  22.             break;  
  23.       }  
  24.   
  25.       if (xmlReader.HasAttributes)  
  26.       {  
  27.          while (xmlReader.MoveToNextAttribute())  
  28.          {  
  29.             sb.AppendFormat(" - Attribute: {0} = {1}",  
  30.                               xmlReader.Name,  
  31.                               xmlReader.Value);  
  32.             sb.AppendLine();  
  33.          }  
  34.       }  
  35.    }  
  36.    xmlReader.Close();  
  37.    txtLog.Text = sb.ToString();  
  38. }  
      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();
      }

输出结果如下:

  1. XmlDeclaration: xml=version="1.0" encoding="utf-8"  
  2.   Attribute: version=1.0  
  3.   Attribute: encoding=utf-8  
  4. Element: MyRoot=  
  5. Element: MyChild=  
  6.   Attribute: ID=1  
  7. Element: MyGrandChild=  
  8. Element: MyGrandChild=  
  9. Element: MyGrandChild=  
  10. Element: MyChild=  
  11.   Attribute: ID=2  
  12. Element: MyGrandChild=  
  13. Element: MyGrandChild=  
  14. Element: MyGrandChild=  
  15. Element: MyChild=  
  16.   Attribute: ID=3  
  17. Element: MyGrandChild=  
  18. Element: MyGrandChild=  
  19. Element: MyGrandChild=  
  20. Element: MyChild=  
  21.   Attribute: ID=4  
  22. Element: MyGrandChild=  
  23. Element: MyGrandChild=  
  24. Element: MyGrandChild=  
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》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值