Как использовать XPath для выбора узлов XML – C#
XPath (XML Path Language) основан на DOM-представлении XML-документа. Таким образом, вы можете использовать XPath для поиска определенного узла или узлов в файле XML, которые соответствуют некоторым критериям, определенным в выражении XPath. В статье рассмотрены С# примеры выбора необходимой информации из XML-файла с помощью XPath-запросов. Вы узнаете, как перемещаться по XML-документу и выбирать узлы с помощью XPath.
Чтобы узнать, как использовать метод Evaluate() для навигации по HTML-документу и выбора узлов с помощью запроса XPath, см. статью Как использовать XPath – Evaluate() метод.
Вы можете загрузить файлы данных и полные примеры C#, демонстрирующие использование метода Evaluate() для запросов XPath, из GitHub.
Запрос XPath – выбор узлов из XML-файла
В этих примерах показано, как выбрать необходимую информацию из XML-файла с помощью языка запросов XPath. Давайте взглянем на XML-документ cars.xml. Этот тестовый XML-документ содержит базу данных автомобильных дилеров, их номера телефонов, имена и список автомобилей, которыми они владеют.
Давайте последовательно составим выражения XPath, которые будут выбирать имена, номера телефонов и список интересующих вас автомобилей. XPath обладает мощными возможностями, как вы увидите в следующих примерах:
Выберите все узлы “Dealer” в файле XML.
XPath используется программно для оценки выражений и выбора определенных узлов в XML-документе. Чтобы выбрать узлы из XML, используйте метод Evaluate().
Начнем с простого XPath-запроса для всех узлов “Dealer” в XML-документе. В следующем примере используется выражение XPath //Dealer
. Он выбирает все элементы “Dealer” независимо от того, где они находятся в документе:
C# code
1var dealers = doc.Evaluate("//Dealer", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
JavaScript code
1var dealers = document.evaluate("//Dealer", document, null, XPathResult.ANY_TYPE, null);
Таким образом, вы выбираете информацию обо всех дилерах из XML-файла без каких-либо ограничений. Выражение XPath //Dealer
позволяет вам выбрать все вложенные узлы с именем “Dealer”.
Выберите узлы, используя оси XPath – descendant::
Запрос XPath с ограничениями по дате выпуска автомобиля
Усложним XPath-запрос и добавим ограничение на год выпуска автомобиля.
Вы можете использовать оси XPath в выражениях XPath. Оси XPath представляют отношение к текущему узлу и используются для поиска узлов относительно этого узла в дереве документа. Ось «потомок» (descendant) указывает на всех дочерних элементов узла контекста, всех их дочерних элементов и т.д. Другими словами, потомок выбирает всех потомков (детей, внуков и т. д.) текущего узла. Например, Descendant::Car выбирает всех потомков Car текущего узла.
Итак, давайте создадим выражение XPath, чтобы найти дилеров, у которых есть автомобиль descendant::Car
с датой выпуска модели новее 2005 года descendant::Model > 2005
. С точки зрения дерева DOM мы ищем всех дочерних элементов “Dealer” с именем “Car”, у которых есть дочерний элемент с именем “Model”, значение которого превышает “2005”. В следующем примере используется выражение XPath //Dealer[descendant::Car[descendant::Model > 2005]]
.
C# code
1var dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
JavaScript code
1var dealers = document.evaluate("//Dealer[descendant::Car[descendant::Model > 2005]]", document, null, XPathResult.ANY_TYPE, null);
XPath-запрос с ограничениями на дату производства и цену автомобиля
На следующем шаге добавим больше ограничений: введем ограничение на цену автомобиля and descendant::Price < 25000
.
Выражение XPath выглядит следующим образом: //Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]
.
Примечание: условия по цене и году выпуска объединены знаком and
, что означает выполнение обоих этих условий одновременно:
C# code
1var dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
JavaScript code
1var dealers = document.evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", document, null, XPathResult.ANY_TYPE, null);
В результате будут выбраны только дилеры, имеющие автомобиль с датой выпуска не старше 2005 года и ценой менее 25 000.
Пример C#, часть 1. Выбор узлов из XML-файла
Рассмотрим, как выбрать из XML-файла дилеров, у которых есть автомобиль с датой выпуска не старше 2005 года и ценой менее 25 000, и вывести в консоль необходимую информацию. Вы должны выполнить несколько шагов:
- Загрузите существующий XML-файл ( cars.xml).
- Используйте метод
Evaluate() класса
Document и передайте ему выражение XPath
//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]
и другие параметры. - Переберите полученные узлы и выведите их содержимое на консоль.
- Вы получите список дилеров со всем содержимым узлов “Dealer”.
1// Create an instance of a document
2using (var doc = new HTMLDocument(Path.Combine(DataDir, "cars.xml")))
3{
4 // Select dealers that match XPath expression
5 var dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
6 Node dealer;
7
8 // Iterate over the selected dealers
9 while ((dealer = dealers.IterateNext()) != null)
10 {
11 Console.WriteLine(dealer.TextContent);
12 }
13}
Пример C#, часть 2. Выбор конкретной информации из выбранных узлов
В предыдущей части примера запрос XPath выбирает все содержимое узла “Dealer”, которое соответствует выражению XPath //Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]
. Но вы можете выбрать и распечатать только интересующую вас информацию из всего содержимого выбранного диллера.
В этом примере (
cars.xml) внутренний запрос был добавлен внутри цикла к выбранным узлам “Dealer”. Запрос собирает в виде строки информацию о дилере, такую как “Name” и “Telephone”: concat('Dealer name: ', Name, 'Telephone: ', Telephone)"
. Обратите внимание на второй переданный параметр в
Evaluate(expression
, contextNode
, resolver
, type
, result
) метод. Это узел, относительно которого будет выполняться запрос – текущий узел “Dealer”. Этот запрос объединяет содержимое узлов с именами Name
и Telephone
.
Примечание. запрос использует ожидаемый тип результата строки XPathResultType.String
, а значение результата получается через свойство StringValue
, а не через итератор узла.
К списку выбранных дилеров можно добавить атрибут CarID
, указывающий на конкретный автомобиль. Запрос должен быть сделан с выражением XPath .//Car[descendant::Model > 2005 and descendant::Price < 25000]/@CarID
. В добавленном запросе есть несколько функций; давайте посмотрим на них:
- запрос выбирает все вложенные автомобили относительно текущего узла
.//Car
, а не относительно корня дерева//Car
; - в выражении XPath мы запрашиваем интересующий нас атрибут
/@CarID
для выбранных автомобилей.
1// Create an instance of a document
2using (var doc = new HTMLDocument(Path.Combine(DataDir, "cars.xml")))
3{
4 // Select dealers that match XPath expression
5 var dealers = doc.Evaluate("//Dealer[descendant::Car[descendant::Model > 2005 and descendant::Price < 25000]]", doc, doc.CreateNSResolver(doc), XPathResultType.Any, null);
6 Node dealer;
7
8 // Iterate over the selected dealers
9 while ((dealer = dealers.IterateNext()) != null)
10 {
11 // Get and print Dealer name and Telephone
12 var dealerInfo = doc.Evaluate("concat('Dealer name: ', Name/text(), ' Telephone: ', Telephone/text())", dealer, doc.CreateNSResolver(doc), XPathResultType.String, null);
13 Console.WriteLine(dealerInfo.StringValue);
14
15 // Select and print CarID that match XPath expression
16 var carIds = doc.Evaluate(".//Car[descendant::Model > 2005 and descendant::Price < 25000]/@CarID", dealer, doc.CreateNSResolver(doc), XPathResultType.Any, null);
17 Node carId;
18
19 while ((carId = carIds.IterateNext()) != null)
20 {
21 Console.WriteLine("Car id: " + carId.TextContent);
22 }
23 }
24}
В результате получаем список дилеров с именами, телефонами и идентификационными кодами интересующих нас автомобилей.
Aspose.HTML предлагает бесплатные Веб-приложения HTML, которые представляют собой онлайн-коллекцию конвертеров, слияний, загрузчиков, инструментов SEO, генераторов HTML-кода и многое другое. Приложения работают в любой операционной системе с веб-браузером и не требуют установки дополнительного программного обеспечения. Это быстрый и простой способ эффективно и действенно решать ваши задачи, связанные с HTML.