使用 XPath 导航选择节点

XML 文档对象模型 (DOM) 包含的方法使您可以使用 XML 路径语言 (XPath) 浏览功能查询 DOM 中的信息。 可以使用 XPath 查找单个特定节点,或查找与某个条件匹配的所有节点。

XPath 选择方法

DOM 类提供两种 XPath 选择方法:SelectSingleNode 方法和 SelectNodes 方法。 SelectSingleNode 方法返回符合选择条件的第一个节点。 SelectNodes 方法返回包含匹配节点的 XmlNodeList

下面的示例使用 SelectSingleNode 方法来选择其作者姓氏符合指定条件的第一个 book 节点。 bookstore.xml 文件(在本主题末尾提供)用作输入文件。

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 方法来选择其价格大于指定金额的所有书节点。 然后,以编程方式将选定列表中的每本书的价格减去 10%。 最后,将更新的文件写入控制台。 bookstore.xml 文件(在本主题末尾提供)用作输入文件。

' 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 查询。 设置 XPath 查询的起始点即设置了上下文节点,该节点是 XPath 查询的起始点。 如果不希望在文档元素处开始,而是希望从文档元素的第一个子级开始,可以编写 Select 语句的代码,如下所示:

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

所有 XmlNodeList 对象都与基础文档同步。 因此,如果循环访问节点列表并修改某个节点的值,则该节点在包含它的文档中也被更新。 请注意,在上一个示例中,在选定的 XmlNodeList 中修改节点时,也会修改基础文档。

注意

修改基础文档时,最好重新运行此 Select 语句。 如果修改的节点可能导致该节点被添加到节点列表(当先前没有添加它时),或者现在会导致它从节点列表中被移除,则无法保证节点列表现在是精确的。

XPath 表达式中的命名空间

XPath 表达式可以包含命名空间。 使用 XmlNamespaceManager 支持命名空间解析。 如果 XPath 表达式包含前缀,前缀和命名空间 URI 对必须添加到 XmlNamespaceManager,并且 XmlNamespaceManager 传递给 SelectNodes(String, XmlNamespaceManager)SelectSingleNode(String, XmlNamespaceManager) 方法。 请注意,上面的代码示例使用 XmlNamespaceManager 来解析 bookstore.xml 文档的命名空间。

注意

如果 XPath 表达式不包含前缀,则假定命名空间统一资源标识符 (URI) 是空的命名空间。 如果 XML 包含默认命名空间,仍必须将前缀和命名空间 URI 添加到 XmlNamespaceManager;否则,不会选择任何节点。

输入文件

下面的 bookstore.xml 文件在本主题的示例中用作输入文件。

<?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>  

请参阅