Xpath примеры. Применение оси self. Выбор неизвестных заранее узлов

XPath – это язык для записи выражений. Он имеет фундаментальное значе­ние для обработки XML-документов. Нельзя овладеть XSLT, не зная XPath, точ­но так же, как нельзя выучить английский язык, не зная алфавита. Некоторые читатели первого издания этой книги пеняли мне за то, что я не включил в нее основ XPath. Эта глава добавлена отчасти, чтобы удовлетворить их, но главным образом потому, что в спецификации XPath 2.0 выразительная мощь этого языка была значительно усилена. Впрочем, многие рецепты будут рабо­тать и с XPath 1.0.

В XSLT 1.0 язык XPath используется тремя способами. Во-первых, в шабло­нах он служит для адресации частей преобразуемого документа. Во-вторых, он применяется для задания образцов в правилах сопоставления. В-третьих, с помо­щью встроенных в XPath операторов и функций выполняются простые математи­ческие операции и манипуляции со строками.

В XSLT 2.0 связь с XPath 2.0 сохранена и даже стала прочнее. В нем широ­ко используются новые вычислительные средства, появившиеся в XPath 2.0. Можно даже сказать, что дополнительные возможности XSLT 2.0 – во многом результат нововведений в XPath 2.0, к числу которых относятся последова­тельности, регулярные выражения, условные и итеративные выражения, сис­тема типов, совместимая со спецификацией XML Schema, а также множество новых встроенных функций.

Каждый рецепт в этой главе – это подборка мини-рецептов для решения опре­деленного класса задач, возникающих в XPath в контексте XSLT. Все XPath-выра- жения прокомментированы в соответствии с принятым в XPath 2.0 соглашением (: комментарий:), но пользователям XPath 1.0 следует иметь в виду, что это недопустимая синтаксическая конструкция. Пустой результат вычисления XPath-выражения мы будем обозначать (), именно так в XPath 2.0 записывается пустая последовательность.

Требуется отобрать узлы XML-дерева с учетом сложных взаимосвязей в иерар­хической структуре.

Во всех приведенных ниже примерах используются оси. В каждой группе для демонстрации берется некий XML-документ, в котором контекстный узел выделен полужирным шрифтом. Поясняется, что является результатом вы­числения пути, при этом показано, какие элементы отбираются относительно выделенного контекста. В некоторых случаях для иллюстрации тонкостей вычис­ления конкретного выражения рассматриваются и другие узлы, помимо кон­текстного.

Дочерняя ось и ось потомков

Дочерняя ось принимается в XPath по умолчанию. Иными словами, явно ука­зывать ось child:: необязательно, но, если вы хотите быть педантом, то можете и указать. Спуститься по XML-дереву глубже, чем на один уровень, позволяют

оси descendant:: и descendant-or-self::. Первая не включает сам кон­текстный узел, вторая – включает.

(: Отобрать все дочерние элементы с именем X

X (: то же, что child::X)

Результат:

(: Отобрать первый дочерний элемент с именем X X

Результат:

(: Отобрать последний дочерний элемент с именем X X

Результат:

(: Отобрать первый дочерний элемент при условии, что его имя X. Иначе пусто *

Результат:

(: Отобрать последний дочерний элемент при условии, что его имя X. Иначе пусто

*

Результат: ()

(: Отобрать последний дочерний элемент при условии, что его имя Y. Иначе пусто

*

Результат:

(: Отобрать всех потомков с именем X descendant::X

Результат:

(: Отобрать контекстный узел, если его имя X, а также всех потомков с именем X descendant-or-self::X

Результат:

(: Отобрать контекстный узел и всех его потомков descendant-or-self::*

Результат:

Оси братьев

Оси братьев называются preceding-sibling:: и following-sibling::. Ось preceding-sibling содержит братьев, предшествующих контекстному узлу, а ось following-sibling – следующих за ним. Братьями, естественно, называются дети одного родителя. Почти во всех примерах ниже используется ось preceding-sibling::, но вам не составит труда вычислить результат и для оси following-sibling::.

Имейте в виду, что в позиционном выражении вида preceding- sibling::* вы ссылаетесь на непосредственно предшествующего брата в порядке обратного отсчета от контекстного узла, а не первого брата в порядке доку­мента. Некоторых смущает тот факт, что результирующая последовательность воз­вращается в порядке документа вне зависимости от того, используется ось preceding-sibling:: или following-sibling::. В выражении../X, строго говоря, никакая ось не указана; это просто способ отобрать предшествующего и пос­ледующего брата с именем X, а также сам контекстный узел, если он называется X. Формально это сокращенная запись выражения parent::node()/X. Отметим, что выражения(preceding-sibling::*) и(following-sibling::*) от­бирают первого предшествующего или последующего брата в порядке документа.

(: Отобрать всех братьев с именем A, предшествующих контекстному узлу preceding-sibling::A

Результат:

(: Отобрать всех братьев с именем A, следующих за контекстным узлом following-sibling::A

Результат:

(: Отобрать всех братьев, предшествующих контекстному узлу preceding-sibling::*

Результат:

(: Отобрать первого предшествующего брата с именем A в обратном порядке документа preceding-sibling::A

Результат:

(: Отобрать первого предшествующего брата в обратном порядке документа при условии, что его имя A preceding-sibling::*

Результат: ()

(: Если бы контекстным был узел , то в результате мы получили бы

(: Отобрать всех предшествующих братьев, кроме элементов с именем A preceding-sibling::*

Результат:

(: В следующих примерах используется такой тестовый документ

(: Элемент, непосредственно предшествующий контекстному узлу при усло­вии, что у того есть дочерний элемент с именем A

preceding-sibling::*[A]

Результат: ()

(: Первый из предшествующих контекстному узлу элементов, у которого есть дочерний элемент с именем A

preceding-sibling::*[A]

Результат: …

(: XPath 2.0 позволяет более гибко выбирать элементы с учетом про­странств имен. В следующих примерах используется такой XML-документ

(: Отобрать всех предшествующих братьев контекстного узла, для которых пространство имен ассоциировано с префиксом NS preceding-sibling::NS:*

Результат:

(: Отобрать всех предшествующих братьев контекстного узла, для которых локальное имя равно A preceding-sibling::*:A

Результат:

Родительская ось и ось предков

Родительская ось (parent::) относится к родителю контекстного узла. Не путайте выражение parent::X с../X. Первое порождает последовательность, ко­торая содержит в точности один элемент, если имя родителя контекстного узла – X, и пуста в противном случае. Второе – это сокращенная запись выражения parent::node()/X, которое отбирает всех братьев контекстного узла с именем X, в том числе и сам этот узел, если он называется X.

С помощью осей ancestor:: и ancestor-or-self:: можно перемещать­ся вверх по XML-дереву (переходя к родителю, деду, прадеду и т.д.). В первом случае сам контекстный узел исключается, во втором – включается.

(: Возвращает родителя контекстного узла, при условии, что он называется X, в противном случае - пустую последовательность. parent::X

(: Возвращает родителя контекстного узла. Результат может быть пустым, только если контекстный узел является элементом верхнего уровня. parent::*

(: Возвращает родителя, если его пространство имен ассоциировано с префиксом X. Префикс должен быть определен, иначе произойдет ошибка.

(: Возвращает родителя независимо от его пространства имен при условии, что локальное имя равно X.:) parent::*:X

(: Возвращает всех предков (включая родителя) с именем X. ancestor::X

(: Возвращает контекстный узел, если он называется X, а также всех предков с именем X. ancestor-or-self::X

Оси предшественников и последователей

Оси preceding:: и following:: могут отбирать очень много узлов, по­скольку учитываются все узлы, предшествующие контекстному (или следующие за ним) в порядке документа, исключая предков в случае оси following:: или потомков для оси preceding::. Не забывайте также, что обе оси не включают узлы, соответствующие пространствам имен и атрибутам.

(: Все предшествующие узлы с именем X. preceding::X

(: Ближайший предшественник с именем X. preceding::X

(: Самый дальний последователь с именем X. following::X

Обсуждение

В языке XPath понятие оси служит для того, чтобы выделить в дереве доку­мента различные подмножества узлов относительно некоторого узла, называемо­го контекстным. В общем случае эти подмножества пересекаются, но оси ancestor, descendant, following, preceding и self разбивают документ на непересекающиеся части, в совокупности содержащие все узлы (за исключением тех, что соответ­ствуют пространствам имен и атрибутам). Контекстный узел устанавливается языком, в который погружен XPath. В случае XSLT контекстный узел устанавли­вают следующие конструкции:

Сопоставление с шаблоном (…);

Xsl:apply-templates.

Свободное владение языком написания путевых выражений – необходимое условие для выполнения как простых, так и сложных преобразований. Опыт про­граммирования на традиционных языках часто служит причиной путаницы и ошибок при работе с XPath. Например, я часто ловил себя на том, что писал что- то типа , имея в виду . Возможно, это объясняется тем, что последнее выражение – интуитивно менее понятный способ выразить такое условие: «если имя непосредственно предше­ствующего брата равно X».

Конечно, нет никакой возможности показать все полезные комбинации осей в путевых выражениях. Но, если вы поймете приведенные выше примеры, то смо­жете разобраться, что означает выражение preceding-sibling::X/ descendant::Z и еще более сложные.

Мангано Сэл XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

Xpath - это язык запросов к элементам xml или xhtml документа. Также как SQL, xpath является декларативным языком запросов. Чтобы получить интересующие данные, необходимо всего лишь создать запрос, описывающий эти данные. Всю «черную» работу за вас выполнит интерпретатор языка xpath.
Очень удобно, не правда ли? Давайте посмотри какие возможности предлагает xpath для доступа к узлам веб-страниц.

Создание запроса к узлам веб-страниц Предлагаю вашему вниманию небольшую лабораторную работу, в ходе которой я продемонстрирую создание xpath запросов к веб-странице. Вы сможете повторить приведенные мной запросы и, самое главное, попробуете выполнить свои. Я надеюсь, что благодаря этому статья будет одинаково интересна новичкам и программистам знакомым с xpath по xml.

Для лабораторной нам понадобятся:
- веб-страница xhtml;
- браузер Mozilla Firefox с дополнениями;
- firebug ;
- firePath ;
(вы можете использовать любой другой браузер с визуальной поддержкой xpath)
- немного времени.

В качестве веб-страницы для проведения эксперимента предлагаю главную страницу сайта консорциума всемирной паутины ("http://w3.org "). Именно эта организация разрабатывает языки xquery(xpath), спецификацию xhtml и многие другие стандарты интернета.

Задача Получить из xhtml-кода главной страницы w3.org информацию о конференциях консорциума при помощи запросов xpath.
Приступим к написанию xpath запросов.
Первый Xpath запрос Открываем закладку Firepath в FireBug, выделяем с селектором элемент для анализа, нажимаем: Firepath создал xpath запрос к выбранному элементу.

Если вы выделили заголовок первого события, то запрос будет таким:

/a

После удаления лишних индексов запрос станет соответствовать всем элементам типа «заголовок».

Firepath подсвечивает элементы, которые соответствуют запросу. Вы можете в реальном времени увидеть, какие узлы документа соответствуют запросу.

Запрос для получения информации о местах проведения конференций:
.//*[@id="w3c_home_upcoming_events"]/ul/li/div/p

Так мы получим список спонсоров:
.//*[@id="w3c_home_upcoming_events"]/ul/li/div/p

Синтаксис xpath Давайте вернемся к созданным запросам и разберемся в том, как они устроены.
Рассмотрим подробно первый запрос

В этом запросе я выделил три части для демонстрации возможностей xpath. (Деление на части уловное)

Первая часть
.// - рекурсивный спуск на ноль или более уровней иерархии от текущего контекста. В нашем случае текущий контекст это корень документа

Вторая часть
* - любой элемент,
[@id="w3c_home_upcoming_events"] – предикат, на основе которого осуществляем поиск узла, имеющего атрибут id равным "w3c_home_upcoming_events". Идентификаторы элементов XHTML должны быть уникальны. Поэтому запрос «любой элемент с конкретным ID» должен вернуть единственный искомый нами узел.

Мы можем заменить * на точное имя узла div в этом запросе
div[@id="w3c_home_upcoming_events"]

Таким образом, мы спускаемся по дереву документа до нужного нам узла div[@id="w3c_home_upcoming_events"]. Нас абсолютно не волнует, из каких узлов состоит DOM-дерево и сколько уровней иерархии осталось выше.

Третья часть
/ul/li/div/p/a –xpath-путь до конкретного элемента. Путь состоит из шагов адресации и условия проверки узлов (ul, li и т.д.). Шаги разделяются символом " /"(косая черта).

Коллекции xpath Не всегда удается получить доступ к интересующему узлу с помощью предиката или шагов адресации. Очень часто на одном уровне иерархии находится насколько узлов одинакового типа и необходимо выбрать «только первые» или «только вторые» узлы. Для таких случаев предусмотрены коллекции.

Коллекции xpath позволяют получить доступ к элементу по его индексу. Индексы соответствуют тому порядку, в котором элементы были представлены в исходном документе. Порядковый номер в коллекциях отсчитывается от единицы.

Исходя из того, что «место проведения» всегда второй параграф после «названия конференции», получаем следующий запрос:
.//*[@id="w3c_home_upcoming_events"]/ul/li/div/p
Где p – второй элемент в наборе для каждого узла списка /ul/li/div.

Аналогично список спонсоров мы можем получить запросом:
.//*[@id="w3c_home_upcoming_events"]/ul/li/div/p

Некоторые функции хpath В хpath существует множество функций для работы с элементами внутри коллекции. Я приведу только некоторые из них.

last():
Возвращает последний элемент коллекции.
Запрос ul/li/div/p - возвратит последние параграфы для каждого узла списка «ul».
Функция first() не предусмотрена. Для доступа к первому элементу используйте индекс «1».

text():
Возвращает тестовое содержание элемента.
.//a – получаем все ссылки с текстом «Archive».

position() и mod:
position() - возвращает позицию элемента в множестве.
mod - остаток от деления.

Комбинацией данных функций можем получить:
- не четные элементы ul/li
- четные элементы: ul/li

Операции сравнения

  • < - логическое «меньше»
  • > - логическое «больше»
  • = - логическое «больше либо равно»
ul/li , ul/li - элементы списка начиная с 3го номера и наоборот.

Правильно ли я понимаю, что с помощью XPath нельзя получить значение атрибута узла?

text

/root/@id

Получаем:

А получить 1 нельзя? Ведь получить text можно.

В каком смысле "где"? Это строковое значение объекта, возвращаемого при выполнении выражения XPath.

Во всяком случае Perl"овый модуль XML::LibXML и плагин XPath Tool к редактору jEdit возвращают именно это.

Понятно. В перле.

Разве XPath "где-то" работает по разному?

Ага. Например,

выведут "1". Без кавычек.

Данбала[досье] Вы ничего не путаете?

System.out.println(document.getRootElement().getAttributeValue("id"));

где тут xPath?
Суть то в том, что xPath выражение вида /root/@id должно вернуть по всем правилам объект типа attribute-node, который, разумеется, не есть просто текст. А уж если вы хотите с помощью xPath выражения получить текстовый узел - то, будьте добры, так ему и напишите.

Данбала[досье]

А вот "Perl"овый модуль XML::LibXML и плагин XPath Tool к редактору jEdit" выведут id="1".

Да, извиняюсь, кавычки я случайно пропустил, с кавычками выведут. Но суть это не меняет.

Насчет Вы, если я правильно понимаю, ошибаетесь. Выражение Xpath вернет именно id="1" , просто потом XSLT из id="1" каким-то образом получит 1 .

А System.out.println(document.getRootElement().getAttributeValue("id")); это не XPath, это DOM , вроде?

Я же говорю о "голом" XPath, неважно, в контексте XSLT он применяется или еще где.

Суть то в том, что xPath выражение вида /root/@id должно вернуть по всем правилам объект типа attribute-node, который, разумеется, не есть просто текст. А уж если вы хотите с помощью xPath выражения получить текстовый узел - то, будьте добры, так ему и напишите. С чего бы это? А почему не результат someting.do(...).toString()?

Какой такой someting.do(...).toString()? Я про XPath говорю! XPath может вернуть text(), если узел является текстовым, или node(), вне зависимости от типа. Но тип тип attribute-node не является, понятно, текстовым, соответственно, text() не работает. Вот почему не работает node() - не понимаю, но не работает.

А вы хотите ему по всем правилам выдать text-node, который также объект, т. е., разумеется, не просто текст?

text-node, конечно, не текст, но это не существенно, потом уж как-нибудь прочитаем. attribute-node тоже не текст, но его мы тоже можем потом прочитать. Разница в том, что text-node содержит строго то, что мы хотели, а attribute-node - нет.

Иванов Михаил aka Ivanych[досье] Я сделал ровно вот так:

<script> testpath

В поле я ввёл соответственно: /root/@id/text() и получил значение id. Если вводить /root/@id то получается id="test" .

Иванов Михаил aka Ivanych[досье]

Какой такой someting.do(...).toString()?

Примерно такой:

String xpath = ...; Node node = возвращатель_узов_по_xpath.дай_узлы(xpath); System.out.println(node.getNodeValue());

Я не знаю перл, но аналог getNodeValue() обязан в нем быть.
Иными словами, работайте не с node, а с его value.

Аааа... JavaScript... Все равно примерно также.
Что-нибудь типа:

Xxx.selectNodes(...).nodeValue

Иванов Михаил aka Ivanych[досье]
Я бы пробежался по их свойствам:

With (this.xml.documentElement){ for (var prop in selectNodes(elm.value)) alert(prop) for (var prop in selectNodes(elm.value).xml) alert(prop) }

да уже домой ухожу.

Попробую изложить мысль иначе.

text

Выражение /root вернет text-node, который в текстовом представлении будет равен text .

Выражение /root/text() вернет также text-node, который в текстовом представлении будет равен text .

Т.е. для получения содержимого текстовой ноды можно использовать оператор(или как он там называется) text() .

Выражение /root/@id вернет attribute-node, который в тестовом представлении будет равен id="1" .

Оператор text() для получения содержимого attribute-node неприменим, ибо attribute-node это не текстовая нода. Эксперимент GRAy[досье] , мне кажется, не совсем чистый, ибо я не уверен, что (elm.value) это именно текстовое представление attribute-node, а не результат последующей его обработки как в XSLT . Ну, или, может быть, MSXML действительно так делает, но у меня такого инструмента нет.

Я хочу докопаться до истины и понять, можно ли сделать так, чтобы текстовым представлением attribute-node вместо id="1" было именно 1 , по аналогии с тем, как текстовое значение text-node text можно сделать равным text при помощи оператора text().

olpa[досье] Нет, так всё равно не выйдет.
Иванов Михаил aka Ivanych[досье] Вы чего-то недопоняли в моём примере что и неудивительно;) - я забыл ещё один инпут, торопился...

function testpath(elm){ if (this.xml) null; else this.xml = new ActiveXObject("MSXML2.DomDocument"); this.xml.load(document.getElementById("xmlf").value); alert(this.xml.documentElement.selectNodes(elm.value).xml); }
testpath

elm.value это текст самого xPath выражения. Можете поэкспериментировать. Хотя согласно спецификации xPath узлы атрибутов и не содержат внутри себя "настоящие" текстовые узлы, там однозначно ничего и не сказано о том, как должна вести себя функция text() в случае её применения к атрибутному узлу. Боюсь что такое поведение это инициатива MS , но мне она кажется достаточно логичной.

fetis[досье]
Я работаею с XML средствами модуля XML::LibXML (Perl). В этом модуле есть функция toString(), возвращающая текстовое значение ноды, возвращенной выражением XPath. Эта функция прекрасно работает с текстовыми узлами.

И вот возникла задача получения списка значений атрибутов. Атрибут - не текстовая нода, поэтому извлекать значение надо функцией nodeValue(), а не toString(). Соответственно, возникла мысль - а нельзя ли заставить XPath вернуть именно текстовую ноду и работать со всеми нодами единообразно.

Т.е. мой вопрос чисто академический, проблемы, повторяю, нет.

XPath используется для навигации по элементам и атрибутам XML-документа. XPath является одним из основных элементов в стандарте XSLT консорциума W3C.

1 Что такое XPath

Выражения XPath

XPath использует выражения пути для выбора отдельных узлов или набора узлов в документе XML. Эти выражения очень похожи на выражения, которые вы видите, когда работаете с традиционной файловой системой компьютера.

Стандартные функции XPath

XPath включает в себя более 100 встроенных функций. Есть функции для строковых и числовых значений, даты и времени, сравнения узлов и манипулирования QName, управления последовательностями, булевых значений, и многое другое.

XPath используется в XSLT

XPath является одним из основных элементов в стандарте XSLT. Без знания XPath вы не будете иметь возможность создавать XSLT-документы.

2 Терминология XPath Узлы

В XPath существует семь видов узлов: элемент, атрибут, текст, пространство имён, инструкции обработки, комментарии и узлы документа. XML-документы обрабатываются в виде деревьев узлов. Верхний элемент дерева называется корневым элементом. Посмотрите на следующий документ XML:

Harry Potter J. K. Rowling 2005 29.99

Пример узлов в документе XML выше:

(корневой элемент) J. K. Rowling (узел) lang="en" (атрибут) Атомарные значения

Атомарные значения являются узлами, не имеющие детей или родителей. Пример атомарных значений:

J. K. Rowling "en"

Элементы

Элементы - это атомарные значения или узлы.

3 Отношения узлов Родитель

Каждый элемент и атрибут имеет одного родителя. В следующем примере элемент «книга» (book) является родителем элементов «название» (title), «автор» (author), «год» (year) и «цена» (price):

Harry Potter J K. Rowling 2005 29.99

Потомки

Узлы элементов могут иметь ноль, один или более потомков. В следующем примере элементы «название», «автор», «год» и «цена» - они все потомки элемента книга:

Harry Potter J K. Rowling 2005 29.99

Элементы одного уровня

Это узлы, которые имеют одного и того же родителя. В следующем примере элементы «название», «автор», «год» и «цена» все являются элементами одного уровня:

Harry Potter J K. Rowling 2005 29.99

Предки

Родитель узла, родитель родителя узла и т.д. В следующем примере предки элемента «название» (title) - это элементы «книга» (book) и «книжный магазин» (bookstore):

Harry Potter J K. Rowling 2005 29.99

Потомки

Дети узла, дети детей узла и т.д. В следующем примере потомками элемента «книжный магазин» являются элементы «книга», «название», «автор», «год» и «цена»:

Harry Potter J K. Rowling 2005 29.99

4 Синтаксис XPath

XPath использует выражения пути для выбора узлов или множества узлов в документе XML. Узел можно выбрать, следуя пути или по шагам. Мы будем использовать следующий XML-документ в приведённых ниже примерах.

Harry Potter 29.99 Learning XML 39.95

Выбор узлов

С помощью выражений XPath для выбора узлов в документе XML можно выбрать узел, следуя пути или шагам. Самые полезные выражения пути перечислены ниже:

В приведенной ниже таблице перечислены некоторые пути выражения и результат выполнения выражения:

Выражение XPath Результат
bookstore Выбирает все узлы с именем "bookstore"
/bookstore Выбирает корневой элемент книжного магазина

Примечание: Если путь начинается с косой черты (/), он всегда представляет собой абсолютный путь к элементу!

bookstore/book Выбирает все элементы «книга» (book), которые являются потомками элемента «книжный магазин» (bookstore)
//book Выбирает все элементы «книга» независимо от того, где они находятся в документе
bookstore//book Выбирает все элементы «книга», которые являются потомком элемента «книжный магазин», независимо от того, где они находятся под элементом «книжный магазин»
//@lang Выбирает все атрибуты, которые называются "lang"
Предикаты

Предикаты используются для поиска специфического узла или узла, который содержит специфическое значение. Предикаты всегда обрамляются квадратными скобками. В приведённой ниже таблице перечислены некоторые выражения пути с предикатами, и результат выражения:

Выражения XPath Результат
/bookstore/book Выбирает первый элемент «книга», который является потомком элемента «книжный магазин».

Примечание: В IE 5,6,7,8,9 первый узел имеет индекс , но в соответствии с рекомендациями W3C, это . Для решения этой проблемы в IE, задаётся опция "SelectionLanguage" для XPath:

На JavaScript: xml .setProperty("SelectionLanguage", "XPath");
/bookstore/book Выбирает последний элемент «книга» (book), который является дочерним элементом элемента «книжный магазин» (bookstore)
/bookstore/book Выбирает предпоследний элемент «книга», который является дочерним элементом элемента «книжный магазин»
/bookstore/book Выбор первых двух элементов «книга», которые являются потомками элемента «книжный магазин»
//title[@lang] Выбирает все элементы «название» (title), которые имеют атрибут с именем "lang"
//title[@lang="en"] Выбирает все элементы «название», которые имеют атрибут «язык» со значением "en"
/bookstore/book Выбирает все элементы «книга» после элемента «книжный магазин», которые имеют элемент «цена» со значением больше, чем 35.00
/bookstore/book/title Выбирает все элементы «название» книги элемента «книжный магазин», которые имеют элемент «цена» со значением больше, чем 35.00
Выбор неизвестных узлов

Специальные символы XPath могут использоваться для выбора неизвестных XML узлов.

В приведённой ниже таблице мы перечислили некоторые пути выражения и результаты выражений:

Выбор нескольких путей

С помощью оператора | в выражениях XPath вы можете выбрать несколько путей. В таблице ниже перечислены несколько выражений путей и результаты их применения:

5 Оси XPath

Мы будем использовать следующий XML документ далее в примере.

Harry Potter 29.99 Learning XML 39.95

Оси определяют наборы узлов, относительно текущего узла.

Название оси Результат
ancestor Выбирает всех предков (родителей, прародителей и т.д.) текущего узла
ancestor-or-self Выбирает всех предков (родителей, прародителей и т.д.) текущего узла и сам текущий узел
attribute
child
descendant Выбирает всех потомков (детей, внуков и т.д.) текущего узла
descendant-or-self Выбирает всех потомков (детей, внуков и т.д.) текущего узла и сам текущий узел
following Выбирает всё в документе после закрытия тэга текущего узла
following-sibling Выбирает все узлы одного уровня после текущего узла
namespace Выбирает все узлы в данном пространстве имён (namespace) текущего узла
parent Выбирает родителя текущего узла
preceding Выбирает все узлы, которые появляются перед текущим узлом в документе, за исключением предков, узлов атрибутов и узлы пространства имён
preceding-sibling Выбирает всех братьев и сестёр до текущего узла
self Выбирает текущий узел
6 Выражения пути выборки

Путь определения местоположения может быть абсолютным или относительным. Абсолютный путь расположения начинается с косой черты (/), а относительный - нет. В обоих случаях путь выборки состоит из одного или нескольких шагов, разделённых косой чертой:

Абсолютный путь расположения:

/step/step/...

Относительный путь выборки расположения:

Step/step/...

Каждый шаг оценивается по узлам в текущем наборе узлов. Шаг состоит из:

  • ось (определяет древовидную связь между выбранными узлами и текущим узлом);
  • проверка узла (идентифицирует узел в пределах оси);
  • ноль или более предикатов (для дальнейшего уточнения выбранного набор узлов)

Синтаксис шага выборки такой:

Axisname::nodetest имяОси::проверкаУзла[предиктор]

Пример Результат
child::book Выбирает все узлы «книга» (book), которые являются потомками текущего узла
attribute::lang Выбирает атрибут «язык» (lang) текущего узла
child::* Выбирает всех потомков текущего узла
attribute::* Выбирает все атрибуты текущего узла
child::text() Выбирает все текстовые узлы текущего узла
child::node() Выбирает всех ближайших потомков текущего узла
descendant::book Выбирает всех потомков текущего узла
ancestor::book Выбирает всех предков «книга» (books) текущего узла
ancestor-or-self::book Выбирает всех предков «книга» (book) текущего узла - и текущий узел, если он также «книга» (book)
child::*/child::price Выбирает все потомки «цена» (price) через один уровень от текущего узла
7 Операторы XPath

Выражения XPath возвращают как набор узлов, строки, булевы или числовые значения. Ниже представлен список операторов, используемых в выражениях XPath:

Оператор Описание Пример
| Вычисляет два набора узлов //book | //cd
+ Сложение 6 + 4
- Вычитание 6 - 4
* Умножение 6 * 4
div Деление 8 div 4
= Равенство price=9.80
!= Неравенство price!=9.80
< Меньше, чем price9.80
>= Больше или равно price≤9.80
or Или price=9.80 or price=9.70
and И price>9.00 and price35

Следующий пример выбирает все узлы с ценами выше 35:

/bookstore/book/price

Выбор узлов заголовков с ценой >35

Следующий пример выбирает все узлы заголовков с ценой выше 35:

/bookstore/book/title