【转】循环递归遍历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>
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:\svse\CDList.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 += "\r\n" + subNode.Value;//当前节点的值 52 53 } 54 55 } 56 57 }
注意:当前节点的另外几个重要属性和方法的用法
属性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: A</Item> 16 17 <!-- Fourteen_ chars in this element.--> 18 19 <Item>1234567890ABCD</Item> 20 21 </Items>
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>
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(); } }
------------------------------------------------------------------------
读例程
------------------------------------------------------------------------
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>
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 }
1 <login> 2 <user name=’zhang’ pwd=’123’/> 3 <user name=’wang’ pwd=’456’/> 4 </login>
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节点