Выбор узлов с помощью 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, в противном случае невозможно будет выбрать узлы. |
Дополнительные сведения о пространствах имен см. в разделе Пространства имен в XML-документе.
Входной файл
Файл 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>