【转】循环递归遍历XML文档或按某要求遍历XML文档

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <catalog>
 4 
 5     <cd>
 6 
 7        <title>Empire Burlesque</title>
 8 
 9        <artist>Bob Dylan</artist>
10 
11        <country>USA</country>
12 
13        <company>Columbia</company>
14 
15        <price>10.90</price>
16 
17        <year>1985</year>
18 
19     </cd>
20 
21     <cd>
22 
23        <title>Unchain my heart</title>
24 
25        <artist>Joe Cocker</artist>
26 
27        <country>USA</country>
28 
29        <company>EMI</company>
30 
31        <price>8.20</price>
32 
33        <year>1987</year>
34 
35     </cd>
36 
37 </catalog>
CDList.xml文档如下:
 1 private void button1_Click(object sender, EventArgs e)
 2 
 3 {
 4 
 5      this.FindNode();
 6 
 7 }
 8 
 9 private void FindNode()
10 
11 {
12 
13      XmlDocument doc = new XmlDocument();
14 
15      doc.Load(@"f:svseCDList.xml");//加载XML文档
16 
17      foreach (XmlNode node in doc.ChildNodes)
18 
19    {
20 
21          if (node.HasChildNodes)//判断是否有子节点
22 
23          {
24 
25               FindNode(node);                  
26 
27          }
28 
29       }
30 
31 }
32 
33  
34 
35 private void FindNode(XmlNode node)
36 
37 {
38 
39     foreach (XmlNode subNode in node.ChildNodes)
40 
41     {
42 
43         FindNode(subNode); //实现递归遍历
44 
45 //利用if语句只对文本节点进行相关的处理。
46 
47         if (subNode.Name == "#text")//#text为文本节点的名字
48 
49         {
50 
51            this.textBox1.Text += "
" + subNode.Value;//当前节点的值
52 
53         }
54 
55      }
56 
57 }
程序.cs文件

注意:当前节点的另外几个重要属性和方法的用法
属性FirstChild,返回当前节点的第一个子节点
属性NextSibling,返回当前节点的第一个兄弟节点

//下面的示例通过XML数据流来读取 XML 文件并显示每个节点。

 1 <?xml version="1.0"?>
 2 
 3 <!-- This is a sample XML document -->
 4 
 5 <!DOCTYPE Items [<!ENTITY number "123">]>
 6 
 7 <Items>
 8 
 9   <Item>Test with an entity: &number;</Item>
10 
11   <Item>Test with a child element <more/> stuff</Item>
12 
13   <Item>Test with a CDATA section <![CDATA[<456>]]> def</Item>
14 
15   <Item>Test with a_ char entity: &#65;</Item>
16 
17   <!-- Fourteen_ chars in this element.-->
18 
19   <Item>1234567890ABCD</Item>
20 
21 </Items>
items.xml 文档如下:
 1 XmlReader reader = XmlReader.Create("item.xml");
 2 
 3 //当第一次创建和初始化 XmlReader 时,没有可用的信息。必须调用 Read 读取第一个节点。
 4 
 5 reader.MoveToContent();
 6 
 7 // Parse the file and display each of the nodes.
 8 
 9 while (reader.Read())
10 
11 {
12 
13   switch (reader.NodeType)
14 
15   {
16 
17       case XmlNodeType.Element:
18 
19           Console.Write("<{0}>", reader.Name);
20 
21           break;
22 
23       case XmlNodeType.Text:
24 
25           Console.Write(reader.Value);
26 
27           break;
28 
29       case XmlNodeType.CDATA:
30 
31           Console.Write("<![CDATA[{0}]]>", reader.Value);
32 
33           break;
34 
35       case XmlNodeType.ProcessingInstruction:
36 
37           Console.Write("<?{0} {1}?>", reader.Name, reader.Value);
38 
39           break;
40 
41       case XmlNodeType.Comment:
42 
43           Console.Write("<!--{0}-->", reader.Value);
44 
45           break;
46 
47       case XmlNodeType.XmlDeclaration:
48 
49           Console.Write("<?xml version='1.0'?>");
50 
51           break;
52 
53       case XmlNodeType.Document:
54 
55           break;
56 
57       case XmlNodeType.DocumentType:
58 
59           Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
60 
61           break;
62 
63       case XmlNodeType.EntityReference:
64 
65           Console.Write(reader.Name);
66 
67           break;
68 
69       case XmlNodeType.EndElement:
70 
71           Console.Write("</{0}>", reader.Name);
72 
73           break;
74 
75   }
76 
77 }
遍历程序片断如下:
1 <book>
2   <title>Pride And Prejudice</title>
3   <price>19.95</price>
4 </book>
下面是book.xml文件
using System;
using System.xml;
 

static void Main(String[] args)

{

  using (XmlReader reader = XmlReader.Create("f:\svse\book.xml"))

  {

     reader.Read();

 

     //检查当前节点是否为元素并将读取器推进到下一个节点

     //该方法先后调用IsStartElement和Read将你定位在输入流中所找到的元素的内容上。

     reader.ReadStartElement("book"); //挖到子节点

                       

     reader.ReadStartElement("title");

     Console.Write("The content of the title element:  ");

      

     // ReadString() 方法,该方法返回元素的内容、文本、空白、重要空白或 CDATA 节点。

         

    // 如果定位在元素上,ReadString 将所有文本、重要的空白、空白和 CDATA 节点串联在一起,

    // 然后将串联在一起的数据作为元素内容返回。当遇到任何标记时,它就会停止。

   Console.WriteLine(reader.ReadString());  

   reader.ReadEndElement();

  

   reader.ReadStartElement("price");

   Console.Write("The content of the price element:  ");

   Console.WriteLine(reader.ReadString());

   reader.ReadEndElement();

   reader.ReadEndElement();      

}

}
//通过XML数据流对XML文档进行处理。

------------------------------------------------------------------------
读例程
------------------------------------------------------------------------

 1 <!-- sample xml file -->
 2     <bookstore>
 3       <book genre='novel' ISBN='10-861003-324'>
 4         <title>The Handmaid's Tale</title>
 5         <price>19.95</price>
 6       </book>
 7       <book genre='novel' ISBN='1-861001-57-5'>
 8         <title>Pride And Prejudice</title>
 9         <price>24.95</price>
10       </book>
11 </bookstore>
XML文件
1 using (XmlReader reader = XmlReader.Create("books.xml"))
2     {
3         reader.ReadToFollowing("book");//一直读取,直到找到具有指定限定名的元素。
4         do
5         {  
6            Console.WriteLine("ISBN: {0}", reader.GetAttribute("ISBN")); //获得指定属性的值
7          }while (reader.ReadToNextSibling("book"));
8          //ReadToNextSibling("book")方法,让 XmlReader 前进到下一个具有指定限定名的同级元素
9 }
//取每个书节点上的ISBN属性
1 <login>
2           <user name=’zhang’ pwd=’123’/>
3           <user name=’wang’ pwd=’456’/>
4 </login>
根据上面实例可以考虑当要读取xml中的用户名和密码时可以这样设计xml文档。
 1 using (XmlReader reader = XmlReader.Create("2books.xml"))
 2    {
 3 
 4         //让 XmlReader 前进到下一个具有指定限定名的子代元素。
 5         reader.ReadToDescendant("book");        // 第一个book
 6 
 7        //跳过当前节点的子级。定位到下一个同级节点上。可能是Whitespace节点
 8         reader.Skip();                                         
 9  
10 
11        //检查当前节点是否是内容节点。
12 
13        //如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。
14         reader.MoveToContent();                    // 第二个book
15     }
跳到子节点

总结:
ReadToFollowing(string)
ReadToNextSibling(string)
ReadToDescendant()
Skip()

以上四个方法都可以定位,它们之间有何区别呢?
ReadToFollowing(string):是从当前位置一直读取,直到找到具有指定限定名的元素。
ReadToNextSibling(string):让 XmlReader 前进到下一个具有指定限定名的同级元素
ReadToDescendant(string):让 XmlReader 前进到下一个具有指定限定名的子代元素
Skip():跳过当前节点的子级。定位到下一个同级节点上。可能是Whitespace节点

原文地址:https://www.cnblogs.com/gebenhagen/p/3373509.html