Выбор узлов с помощью XPath-навигации

Модель DOM содержит методы, позволяющие использовать навигацию языка 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. Если нужно начать не с элемента документа, а с первого дочернего элемента, можно использовать инструкцию выбора следующим образом.

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

Все объекты XmlNodeList синхронизируются с базовым документом. Поэтому если при проходе по списку узлов изменить значение узла, этот узел также обновляется в исходном документе. В вышеприведенном примере обратите внимание, что при изменении узла в выбранном списке узлов XmlNodeList базовый документ также изменится.

Примечание.

При изменении базового документа рекомендуется повторно запустить выбор. Если изменение узла может привести к его добавлению в список узлов, где он ранее отсутствовал, или удалению из списка узлов, точность списка узлов не гарантируется.

Пространства имен в выражениях 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>  

См. также