C#高级编程之处理XML-连载十一

时间:2010年04月12日 点击:223

23.7.1  System.Xml.XPath命名空间

System.Xml.XPath命名空间是建立在速度的基础上的,它提供了XML文档的一种只读视图,但没有编辑功能。这个命名空间中的类XPath可以采用光标的方式在XML文档上进行快速迭代和选择操作。

23-7列出了System.Xml.XPath命名空间中的重要类,并对每个类的功能进行了简单的说明。

  23-7

   

   

XpathDocument

提供整个XML文档的视图,只读

XpathNavigator

提供XPathDocument的浏览功能

XpathNodeIterator

提供节点集的迭代功能,XPath等价于XPath中的节点集

XpathExpression

编译好的XPath表达式,由SelectNodesSelectSingleNodesEvaluate Matches使用

XpathException

XPath异常类

 

1. XpathDocument

XPathDocument没有提供XmlDocument类的任何功能,如果需要编辑功能,就应选择XmlDocument,如果要使用ADO.NET,就应选择XmlDataDocument(见本章后面的内容),如果速度比较重要,就应使用XPathDocument。它有4个重载方法,可以从文件和路径字符串、TextReader对象、XmlReader对象或基于Stream的对象中打开XML文档。

2. XpathNavigator

XPathNavigator包含所需移动和选择元素的所有方法,其中的一些移动方法如表23-8所示。

  23-8

   

   

MoveTo()

XPathNavigator作为参数,移动当前位置到XPathNavigator指定的地方

MoveToAttribute()

移动到指定的属性,其参数是属性名和命名空间

MoveToFirstAttribute()

移动到当前元素中的第一个属性上,如果成功,就返回true

MoveToNextAttribute()

移动到当前元素中的下一个属性上,如果成功,就返回true

MoveToFirst()

移动到当前节点中的第一个同级节点上,如果成功,就返回true。否则返回false

MoveToLast()

移动到当前节点中的最后一个同级节点上,如果成功,就返回true

MoveToNext()

移动到当前节点中的下一个同级节点上,如果成功,就返回true

MoveToPrevious()

移动到当前节点中的上一个同级节点上,如果成功,就返回true

MoveToFirstChild()

移动到当前元素中的第一个子元素上,如果成功,就返回true

MoveToId()

移动到ID参数提供的元素上,文档中需要有一个模式,元素的数据类型必须是ID类型

MoveToParent()

移动到当前节点的父节点上,如果成功,就返回true

MoveToRoot()

移动到文档的根节点上

 

有几个Select()方法可以选择出要操作的节点子集。所有的Select方法都返回一个XPathNodeIterator对象。

还可以使用SelectAncestors() SelectChildren()方法。它们都返回一个XpathNodeIterator对象。Select的参数是一个XPath表达式,其他选择方法的参数是一个XPathNodeType

可以扩展XpathNavigator,使用文件系统或注册表作为存储器,来代替XpathDocument

3. XpathNodeIterator

XPathNodeIterator可以看作是XPath中的NodeList NodeSet,这个对象有3个属性和两个方法:

       Clone—— 创建它本身的一个新副本。

       Count—— XPathNodeIterator对象中的节点数。

       Current—— 返回指向当前节点的XPathNavigator

 

       CurrentPosition()—— 返回表示当前位置的一个整数。

       MoveNext()—— 移动到匹配XPath表达式的下一个节点上,创建XPathNodeIterator

4. 使用XPath命名空间中的类

要理解这些类的用法,最好是查看一下迭代books.xml文档的代码,确定导航是如何工作的。为了使用这些示例,首先需要添加对System.Xml.Xsl System.Xml.XPath命名空间的引用,如下所示:

using System.Xml.XPath;

using System.Xml.Xsl;

这个示例使用了文件booksxpath.xml,它类似于前面使用的books.xml,但booksxpath.xml添加了两本书。下面是窗体代码,这段代码在XPathXSLSample1文件夹中:

private void button1_Click(object sender, System.EventArgs e)

{

   //modify to match your path structure

   XPathDocument doc=new XPathDocument("..\\..\\..\\booksxpath.xml");

   //create the XPath navigator

   XPathNavigator nav=doc.CreateNavigator();

   //create the XPathNodeIterator of book nodes

   // that have genre attribute value of novel

   XPathNodeIterator iter=nav.Select("/bookstore/book[@genre='novel']");

  

   while(iter.MoveNext())

   {

      LoadBook(iter.Current);

   }

}

private void LoadBook(XPathNavigator lstNav)

{

   //We are passed an XPathNavigator of a particular book node

   //we will select all of the descendents and

   //load the list box with the names and values

 

   XPathNodeIterator iterBook=lstNav.SelectDescendants

                              (XPathNodeType.Element, false);

   while(iterBook.MoveNext())

      listBox1.Items.Add(iterBook.Current.Name + ": "

                                               + iterBook.Current.Value);

}

button1_Click()方法中,首先创建XPathDocument(叫做doc),其参数是要打开的文档的文件和路径字符串。下面一行代码创建XPathNavigator

XPathNavigator nav = doc.CreateNavigator();

本例用Select方法获取genre属性值为novel的所有节点,然后使用MoveNext()方法迭代书籍列表中的所有小说。

要把数据加载到列表框中,使用XPathNodeIterator.Current属性,根据XPathNodeIterator指向的节点,创建一个新的XPathNavigator对象。在本例中,为文档中的一个book节点创建一个XPathNavigator

LoadBook()方法提取这个XPathNavigator,调用Select方法的另一个重载方法SelectDescendants创建另一个XPathNavigator,这样,XPathNodeIterator就包含了给LoadBook方法发送的book节点的所有子节点。

然后,在这个XPathNodeIterator上执行另一个MoveNext()循环,给列表框加载元素名称和元素值。在执行代码后,显示23-7所示的屏幕图,注意只列出了小说。

 23-7

如果要把这些书的成本相加,该怎么办?XPathNavigator为此包含了Evaluate方法。Evaluate3个重载方法,第一个包含一个字符串,该字符串就是XPath函数调用。第二个Evaluate重载方法的参数是XPathExpression对象,第三个Evaluate重载方法的参数是XPathExpression XPathNodeIterator。如果对示例进行下述修改(这个版本的代码在XPathXSLSample2)

private void button1_Click(object sender, System.EventArgs e)

{

   //modify to match your path structure

   XPathDocument doc = new XPathDocument("..\\..\\..\\booksxpath.XML");

   //create the XPath navigator

   XPathNavigator nav = doc.CreateNavigator();

   //create the XPathNodeIterator of book nodes

   // that have genre attribute value of novel

   XPathNodeIterator iter = nav.Select("/bookstore/book[@genre='novel']");

   while(iter.MoveNext())

   {

      LoadBook(iter.Current.Clone());

   }

   //add a break line and calculate the sum

   listBox1.Items.Add("========================");

   listBox1.Items.Add("Total Cost = "

              + nav.Evaluate("sum(/bookstore/book[@genre='novel']/price)"));

}

这次,可以看到列表框中书籍的总成本,如图23-8所示。

 23-8

更多DotNet好文章www.zdexe.com

赞助商链接

热门内容

相关内容

联系我们

联系方式