循环递归遍历xml文档的所有节点或按某种要求来遍历xml文档的节点
下面的实例是循环递归遍历xml文档并读取文本节点的内容
CDList.xml文档如下:
<?xml version= " 1.0 " encoding= " UTF-8 "?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price> 10.90</price>
<year> 1985</year>
</cd>
<cd>
<title>Unchain my heart</title>
<artist>Joe Cocker</artist>
<country>USA</country>
<company>EMI</company>
<price> 8.20</price>
<year> 1987</year>
</cd>
</catalog>
private void button1_Click( object sender, EventArgs e)
{
this.FindNode();
}
private void FindNode()
{
XmlDocument doc = new XmlDocument();
doc.Load( @" f:\svse\CDList.xml "); // 加载XML文档
foreach (XmlNode node in doc.ChildNodes)
{
if (node.HasChildNodes) // 判断是否有子节点
{
FindNode(node);
}
}
}
private void FindNode(XmlNode node)
{
foreach (XmlNode subNode in node.ChildNodes)
{
FindNode(subNode); // 实现递归遍历
// 利用if语句只对文本节点进行相关的处理。
if (subNode.Name == " #text ") // #text为文本节点的名字
{
this.textBox1.Text += " \r\n " + subNode.Value; // 当前节点的值
}
}
}
注意:当前节点的另外几个重要属性和方法的用法
属性FirstChild,返回当前节点的第一个子节点
属性NextSibling,返回当前节点的第一个兄弟节点
----------------------------------------------------------------------------------------
// 下面的示例通过XML数据流来读取 XML 文件并显示每个节点。
items.xml 文档如下:
<?xml version= " 1.0 "?>
<!-- This is a sample XML document -->
<!DOCTYPE Items [<!ENTITY number " 123 ">]>
<Items>
<Item>Test with an entity: &number;</Item>
<Item>Test with a child element <more/> stuff</Item>
<Item>Test with a CDATA section <![CDATA[< 456>]]> def</Item>
<Item>Test with a_ char entity: &# 65;</Item>
<!-- Fourteen_ chars in this element.-->
<Item>1234567890ABCD</Item>
</Items>
遍历程序片断如下:
XmlReader reader = XmlReader.Create( " item.xml ");
// 当第一次创建和初始化 XmlReader 时,没有可用的信息。必须调用 Read 读取第一个节点。
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
Console.Write( " <{0}> ", reader.Name);
break;
case XmlNodeType.Text:
Console.Write(reader.Value);
break;
case XmlNodeType.CDATA:
Console.Write( " <![CDATA[{0}]]> ", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.Write( " <?{0} {1}?> ", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.Write( " <!--{0}--> ", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.Write( " <?xml version='1.0'?> ");
break;
case XmlNodeType.Document:
break;
case XmlNodeType.DocumentType:
Console.Write( " <!DOCTYPE {0} [{1}] ", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.Write(reader.Name);
break;
case XmlNodeType.EndElement:
Console.Write( " </{0}> ", reader.Name);
break;
}
}
----------------------------------------------------------------------------------------
下面是book.xml文件
<book>
<title>Pride And Prejudice</title>
<price> 19.95</price>
</book>
// 通过XML数据流对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文件
<!-- sample xml file -->
<bookstore>
<book genre= ' novel ' ISBN= ' 10-861003-324 '>
<title>The Handmaid ' s Tale</title>
<price> 19.95</price>
</book>
<book genre= ' novel ' ISBN= ' 1-861001-57-5 '>
<title>Pride And Prejudice</title>
<price> 24.95</price>
</book>
</bookstore>
// 取每个书节点上的ISBN属性
using (XmlReader reader = XmlReader.Create( " books.xml "))
{
reader.ReadToFollowing( " book "); // 一直读取,直到找到具有指定限定名的元素。
do
{
Console.WriteLine( " ISBN: {0} ", reader.GetAttribute( " ISBN ")); // 获得指定属性的值
} while (reader.ReadToNextSibling( " book "));
// ReadToNextSibling("book")方法,让 XmlReader 前进到下一个具有指定限定名的同级元素
}
根据上面实例可以考虑当要读取xml中的用户名和密码时可以这样设计xml文档。
<login>
<user name=’zhang’ pwd=’ 123’/>
<user name=’wang’ pwd=’ 456’/>
</login>
跳到子节点
using (XmlReader reader = XmlReader.Create( " 2books.xml "))
{
// 让 XmlReader 前进到下一个具有指定限定名的子代元素。
reader.ReadToDescendant( " book "); // 第一个book
// 跳过当前节点的子级。定位到下一个同级节点上。可能是Whitespace节点
reader.Skip();
// 检查当前节点是否是内容节点。
// 如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。
reader.MoveToContent(); // 第二个book
}
总结:
ReadToFollowing( string)
ReadToNextSibling( string)
ReadToDescendant()
Skip()
以上四个方法都可以定位,它们之间有何区别呢?
ReadToFollowing( string):是从当前位置一直读取,直到找到具有指定限定名的元素。
ReadToNextSibling( string):让 XmlReader 前进到下一个具有指定限定名的同级元素
ReadToDescendant( string):让 XmlReader 前进到下一个具有指定限定名的子代元素
Skip():跳过当前节点的子级。定位到下一个同级节点上。可能是Whitespace节点
下面的实例是循环递归遍历xml文档并读取文本节点的内容
CDList.xml文档如下:
<?xml version= " 1.0 " encoding= " UTF-8 "?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price> 10.90</price>
<year> 1985</year>
</cd>
<cd>
<title>Unchain my heart</title>
<artist>Joe Cocker</artist>
<country>USA</country>
<company>EMI</company>
<price> 8.20</price>
<year> 1987</year>
</cd>
</catalog>
private void button1_Click( object sender, EventArgs e)
{
this.FindNode();
}
private void FindNode()
{
XmlDocument doc = new XmlDocument();
doc.Load( @" f:\svse\CDList.xml "); // 加载XML文档
foreach (XmlNode node in doc.ChildNodes)
{
if (node.HasChildNodes) // 判断是否有子节点
{
FindNode(node);
}
}
}
private void FindNode(XmlNode node)
{
foreach (XmlNode subNode in node.ChildNodes)
{
FindNode(subNode); // 实现递归遍历
// 利用if语句只对文本节点进行相关的处理。
if (subNode.Name == " #text ") // #text为文本节点的名字
{
this.textBox1.Text += " \r\n " + subNode.Value; // 当前节点的值
}
}
}
注意:当前节点的另外几个重要属性和方法的用法
属性FirstChild,返回当前节点的第一个子节点
属性NextSibling,返回当前节点的第一个兄弟节点
----------------------------------------------------------------------------------------
// 下面的示例通过XML数据流来读取 XML 文件并显示每个节点。
items.xml 文档如下:
<?xml version= " 1.0 "?>
<!-- This is a sample XML document -->
<!DOCTYPE Items [<!ENTITY number " 123 ">]>
<Items>
<Item>Test with an entity: &number;</Item>
<Item>Test with a child element <more/> stuff</Item>
<Item>Test with a CDATA section <![CDATA[< 456>]]> def</Item>
<Item>Test with a_ char entity: &# 65;</Item>
<!-- Fourteen_ chars in this element.-->
<Item>1234567890ABCD</Item>
</Items>
遍历程序片断如下:
XmlReader reader = XmlReader.Create( " item.xml ");
// 当第一次创建和初始化 XmlReader 时,没有可用的信息。必须调用 Read 读取第一个节点。
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
Console.Write( " <{0}> ", reader.Name);
break;
case XmlNodeType.Text:
Console.Write(reader.Value);
break;
case XmlNodeType.CDATA:
Console.Write( " <![CDATA[{0}]]> ", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.Write( " <?{0} {1}?> ", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.Write( " <!--{0}--> ", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.Write( " <?xml version='1.0'?> ");
break;
case XmlNodeType.Document:
break;
case XmlNodeType.DocumentType:
Console.Write( " <!DOCTYPE {0} [{1}] ", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.Write(reader.Name);
break;
case XmlNodeType.EndElement:
Console.Write( " </{0}> ", reader.Name);
break;
}
}
----------------------------------------------------------------------------------------
下面是book.xml文件
<book>
<title>Pride And Prejudice</title>
<price> 19.95</price>
</book>
// 通过XML数据流对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文件
<!-- sample xml file -->
<bookstore>
<book genre= ' novel ' ISBN= ' 10-861003-324 '>
<title>The Handmaid ' s Tale</title>
<price> 19.95</price>
</book>
<book genre= ' novel ' ISBN= ' 1-861001-57-5 '>
<title>Pride And Prejudice</title>
<price> 24.95</price>
</book>
</bookstore>
// 取每个书节点上的ISBN属性
using (XmlReader reader = XmlReader.Create( " books.xml "))
{
reader.ReadToFollowing( " book "); // 一直读取,直到找到具有指定限定名的元素。
do
{
Console.WriteLine( " ISBN: {0} ", reader.GetAttribute( " ISBN ")); // 获得指定属性的值
} while (reader.ReadToNextSibling( " book "));
// ReadToNextSibling("book")方法,让 XmlReader 前进到下一个具有指定限定名的同级元素
}
根据上面实例可以考虑当要读取xml中的用户名和密码时可以这样设计xml文档。
<login>
<user name=’zhang’ pwd=’ 123’/>
<user name=’wang’ pwd=’ 456’/>
</login>
跳到子节点
using (XmlReader reader = XmlReader.Create( " 2books.xml "))
{
// 让 XmlReader 前进到下一个具有指定限定名的子代元素。
reader.ReadToDescendant( " book "); // 第一个book
// 跳过当前节点的子级。定位到下一个同级节点上。可能是Whitespace节点
reader.Skip();
// 检查当前节点是否是内容节点。
// 如果此节点不是内容节点,则读取器向前跳至下一个内容节点或文件结尾。
reader.MoveToContent(); // 第二个book
}
总结:
ReadToFollowing( string)
ReadToNextSibling( string)
ReadToDescendant()
Skip()
以上四个方法都可以定位,它们之间有何区别呢?
ReadToFollowing( string):是从当前位置一直读取,直到找到具有指定限定名的元素。
ReadToNextSibling( string):让 XmlReader 前进到下一个具有指定限定名的同级元素
ReadToDescendant( string):让 XmlReader 前进到下一个具有指定限定名的子代元素
Skip():跳过当前节点的子级。定位到下一个同级节点上。可能是Whitespace节点