使用 XPath 导航选择节点Select Nodes Using XPath Navigation

XML 文档对象模型 (DOM) 包含的方法使您可以使用 XML 路径语言 (XPath) 浏览功能查询 DOM 中的信息。The XML Document Object Model (DOM) contains methods that allow you to use XML Path Language (XPath) navigation to query information in the DOM. 可以使用 XPath 查找单个特定节点,或查找与某个条件匹配的所有节点。You can use XPath to find a single, specific node or to find all nodes that match some criteria.

XPath 选择方法XPath Select Methods

DOM 类提供两种 XPath 选择方法:SelectSingleNode 方法和 SelectNodes 方法。The DOM classes provide two methods for XPath selection: the SelectSingleNode method and the SelectNodes method. SelectSingleNode 方法返回符合选择条件的第一个节点。The SelectSingleNode method returns the first node that matches the selection criteria. SelectNodes 方法返回包含匹配节点的 XmlNodeListThe SelectNodes method returns an XmlNodeList that contains the matching nodes.

下面的示例使用 SelectSingleNode 方法来选择其作者姓氏符合指定条件的第一个 book 节点。The following example uses the SelectSingleNode method to select the first book node in which the author's last name meets the specified criteria. bookstore.xml 文件(在本主题末尾提供)用作输入文件。The bookstore.xml file (which is provided at the end of this topic) is used as the input file.

Dim doc As New XmlDocument()  
doc.Load("bookstore.xml")  
Dim root As XmlNode = doc.DocumentElement  
  
' Add the namespace.  
Dim nsmgr As New XmlNamespaceManager(doc.NameTable)  
nsmgr.AddNamespace("bk", "urn:newbooks-schema")  
  
' Select and display the first node in which the author's   
' last name is Kingsolver.  
Dim node As XmlNode = root.SelectSingleNode( _  
     "descendant::bk:book[bk:author/bk:last-name='Kingsolver']", nsmgr)  
Console.WriteLine(node.InnerXml)  
// Load the document and set the root element.  
XmlDocument doc = new XmlDocument();  
doc.Load("bookstore.xml");  
XmlNode root = doc.DocumentElement;  
  
// Add the namespace.  
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);  
nsmgr.AddNamespace("bk", "urn:newbooks-schema");  
  
// Select and display the first node in which the author's   
// last name is Kingsolver.  
XmlNode node = root.SelectSingleNode(  
    "descendant::bk:book[bk:author/bk:last-name='Kingsolver']", nsmgr);  
Console.WriteLine(node.InnerXml);  

下一个示例使用 SelectNodes 方法来选择其价格大于指定金额的所有书节点。The next example uses the SelectNodes method to select all the book nodes in which the price is greater than a specified amount. 然后,以编程方式将选定列表中的每本书的价格减去 10%。The price for each book in the selected list is then programmatically reduced by ten percent. 最后,将更新的文件写入控制台。Finally, the updated file is written to the console. bookstore.xml 文件(在本主题末尾提供)用作输入文件。The bookstore.xml file (which is provided at the end of this topic) is used as the input file.

' Load the document and set the root element.  
Dim doc As New XmlDocument()  
doc.Load("bookstore.xml")  
Dim root As XmlNode = doc.DocumentElement  
  
' Add the namespace.  
Dim nsmgr As New XmlNamespaceManager(doc.NameTable)  
nsmgr.AddNamespace("bk", "urn:newbooks-schema")  
  
' Select all nodes where the book price is greater than 10.00.  
Dim nodeList As XmlNodeList = root.SelectNodes( _  
     "descendant::bk:book[bk:price>10.00]", nsmgr)  
For Each book As XmlNode In nodeList  
     Dim price As Double  
     price = Math.Round(Convert.ToSingle( _  
          book.LastChild.InnerText) * 0.9, 2)  
     book.LastChild.InnerText = price.ToString()  
Next  
  
' Display the updated document.  
doc.Save(Console.Out)  
// Load the document and set the root element.  
XmlDocument doc = new XmlDocument();  
doc.Load("bookstore.xml");  
XmlNode root = doc.DocumentElement;  
  
// Add the namespace.  
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);  
nsmgr.AddNamespace("bk", "urn:newbooks-schema");  
  
// Select all nodes where the book price is greater than 10.00.  
XmlNodeList nodeList = root.SelectNodes(  
     "descendant::bk:book[bk:price>10.00]", nsmgr);  
foreach (XmlNode book in nodeList)  
{  
     // Discount prices by 10%.  
     double price;  
     price = Math.Round(Convert.ToSingle(  
          book.LastChild.InnerText) * 0.9, 2);  
     book.LastChild.InnerText = price.ToString();  
}  
  
// Display the updated document.  
doc.Save(Console.Out);  

上面的示例从文档元素开始执行 XPath 查询。The examples above start the XPath query at the document element. 设置 XPath 查询的起始点即设置了上下文节点,该节点是 XPath 查询的起始点。Setting the starting point for the XPath query sets the context node, which is the starting point for the XPath query. 如果不希望在文档元素处开始,而是希望从文档元素的第一个子级开始,可以编写 Select 语句的代码,如下所示:If you do not want to start at the document element, but want to start from the first child of the document element, you can code the select statement as follows:

doc.DocumentElement.FirstChild.SelectNodes(. . . )  
this doc.DocumentElement.FirstChild.SelectNodes(. . .);  

所有 XmlNodeList 对象都与基础文档同步。All XmlNodeList objects are synchronized with the underlying document. 因此,如果循环访问节点列表并修改某个节点的值,则该节点在包含它的文档中也被更新。Therefore, if you iterate through the node list and modify the value of a node, that node is also updated in the document it came from. 请注意,在上一个示例中,在选定的 XmlNodeList 中修改节点时,也会修改基础文档。Notice in the previous example that when a node is modified in the selected XmlNodeList the underlying document is also modified.

备注

修改基础文档时,最好重新运行此 Select 语句。When the underlying document is modified, it is advisable to rerun the select. 如果修改的节点可能导致该节点被添加到节点列表(当先前没有添加它时),或者现在会导致它从节点列表中被移除,则无法保证节点列表现在是精确的。If the node modified is one that could cause the node to be added to the node list when it was not previously, or would now cause it to be removed from the node list, there is no guarantee that the node list is now accurate.

XPath 表达式中的命名空间Namespaces in XPath Expressions

XPath 表达式可以包含命名空间。XPath expressions can include namespaces. 使用 XmlNamespaceManager 支持命名空间解析。Namespace resolution is supported using the XmlNamespaceManager. 如果 XPath 表达式包含前缀,前缀和命名空间 URI 对必须添加到 XmlNamespaceManager,并且 XmlNamespaceManager 传递给 SelectNodes(String, XmlNamespaceManager)SelectSingleNode(String, XmlNamespaceManager) 方法。If the XPath expression includes a prefix, the prefix and namespace URI pair must be added to the XmlNamespaceManager, and the XmlNamespaceManager is passed to the SelectNodes(String, XmlNamespaceManager) or SelectSingleNode(String, XmlNamespaceManager) method. 请注意,上面的代码示例使用 XmlNamespaceManager 来解析 bookstore.xml 文档的命名空间。Notice that the code examples above use the XmlNamespaceManager to resolve the namespace of the bookstore.xml document.

备注

如果 XPath 表达式不包含前缀,则假定命名空间统一资源标识符 (URI) 是空的命名空间。If the XPath expression does not include a prefix, it is assumed that the namespace Uniform Resource Identifier (URI) is the empty namespace. 如果 XML 包含默认命名空间,仍必须将前缀和命名空间 URI 添加到 XmlNamespaceManager;否则,不会选择任何节点。If your XML includes a default namespace, you must still add a prefix and namespace URI to the XmlNamespaceManager; otherwise, no nodes will be selected.

输入文件Input File

下面的 bookstore.xml 文件在本主题的示例中用作输入文件。The following is the bookstore.xml file that is used as the input file in the examples in this topic:

<?xml version='1.0'?>  
<bookstore xmlns="urn:newbooks-schema">  
  <book genre="novel" style="hardcover">  
    <title>The Handmaid's Tale</title>  
    <author>  
      <first-name>Margaret</first-name>  
      <last-name>Atwood</last-name>  
    </author>  
    <price>19.95</price>  
  </book>  
  <book genre="novel" style="other">  
    <title>The Poisonwood Bible</title>  
    <author>  
      <first-name>Barbara</first-name>  
      <last-name>Kingsolver</last-name>  
    </author>  
    <price>11.99</price>  
  </book>  
  <book genre="novel" style="paperback">  
    <title>The Bean Trees</title>  
    <author>  
      <first-name>Barbara</first-name>  
      <last-name>Kingsolver</last-name>  
    </author>  
    <price>5.99</price>  
  </book>  
</bookstore>  

请参阅See also