Самоучитель XPath для начинающих

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

Примечание

Расширяемый язык разметки (сокращенно XML) — это язык разметки, используемый для отображения иерархически структурированных данных в текстовом виде. XML одинаково легко читается как людьми, так и машинами. Одно из его применений — обмен данными между двумя компьютерными системами во всемирной паутине.

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

Мы начнем с модели данных XPath (XDM) и познакомим вас с синтаксисом, который подчеркивает выражения XPath, используемые для локализации элементов XML.

Что такое XPath?

XML Path Language (XPath) — это язык описания путей для XML-документов, разработанный консорциумом W3. XPath предоставляет пользователям синтаксис, не основанный на XML, который позволяет конкретно обращаться к элементам XML-документа.

XPath обычно используется во встроенном хост-языке, который позволяет обрабатывать адресованные элементы XML. XQuery, например, используется для запроса элементов XML, к которым обращается XPath. XSLT использует язык запросов при преобразовании XML-документов.

  • XPath: Навигация в XML-документах
  • XQuery: Запросы к XML-документам
  • XSLT: преобразование XML-документов

3.1, текущая версия XPath, указана в рекомендации W3C от 21 марта 2017 года.

Примечание

Несмотря на постоянное развитие, многочисленные XSLT-процессоры, веб-браузеры и приложения по-прежнему поддерживают только стандарт XPath 1.0 от 1999 года.

Как работает XPath?

В основе XPath лежит модель данных, которая интерпретирует XML-документы как последовательность элементов, расположенных в древовидной структуре. Древовидная структура модели данных XPath сопоставима с объектной моделью документа (DOM). Она также выступает в качестве интерфейса между HTML и динамическим JavaScript в веб-браузере.

В виде путей локализация элементов XML происходит на основе системы каталогов unix. Основными элементами пути локализации являются узлы, оси, тесты узлов и предикаты.

Типы узлов

Отдельные элементы древовидной структуры XPath называются узлами. Упорядочивание узлов происходит как через последовательность документов, так и через вложенность элементов XML.

Модель данных XPath различает семь типов узлов с различными функциями:

  • Узел элемента
  • Узел документа (начиная с XPath 2.0 и далее — ранее они назывались корневыми узлами)
  • узел атрибутов
  • Узел текста
  • Узел пространства имен
  • Узел инструкции по обработке
  • Узел комментария

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

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Order SYSTEM "order.dtd">
<?xml-stylesheet type="text/css" href="style.css"?>

<!--This is a comment!-->

<order date="2019-02-01">
    <address xmlns:shipping="http://localhost/XML/delivery" xmlns:billing="http://localhost/XML/billing">
        <shipping:name>Ellen Adams</shipping:name>
        <shipping:street>123 Maple Street</shipping:street>
        <shipping:city>Mill Valley</shipping:city>
        <shipping:state>CA</shipping:state>
        <shipping:zip>10999</shipping:zip>
        <shipping:country>USA</shipping:country>
        <billing:name>Mary Adams</billing:name>
        <billing:street>8 Oak Avenue</billing:street>
        <billing:city>Old Town</billing:city>
        <billing:state>PA</billing:state>
        <billing:zip>95819</billing:zip>
        <billing:country>USA</billing:country>
    </address>
    <comment>Please use gift wrapping!</comment>
    <items>
        <book isbn="9781408845660">
            <title>Harry Potter and the Prisoner of Azkaban</title>
            <quantity>1</quantity>
            <priceus>22.94</priceus>
            <comment>Please confirm delivery date until Christmas.</comment>
        </book>
        <book isbn="9780544003415">
            <title>The Lord of the Rings</title>
            <quantity>1</quantity>
            <priceus>17.74</priceus>
        </book>
    </items>
</order>

Узел элемента

В древовидной структуре модели данных XPath каждый элемент XML-документа соответствует узлу элемента. Исключение составляют декларация XML и определение документа в начале документа.

Декларация XML:

<!--?xml version="1.0"? encoding="utf-8"?-->

Определение типа документа (DTD):

<!DOCTYPE Order SYSTEM "order.dtd">

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

Первые узлы элементов в последовательности документа называются корневыми элементами.

Например, XML-документ, изображенный выше, содержит узел элемента order в качестве корневого элемента. Он выступает в качестве родительского элемента для подчиненных узлов address, comment и items, которые также содержат дополнительные узлы элементов в качестве дочерних элементов.

Узел документа

Корни древовидной структуры называются узлами документа. В самом XML-документе он не демонстрируется визуально и не представлен в виде текста. Это концептуальный узел, который содержит все остальные элементы узла. Дочерними элементами узла документа являются корневые элементы, а также (где это применимо) узлы инструкций по обработке и узлы комментариев.

Узел атрибутов

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

В примере кода первый узел элемента содержит book и узел атрибута isbn со значением 9781408845660.

<book isbn="9781408845660">

Узлы атрибутов считаются частью узла элемента, но не дочерним элементом элемента.

Текстовый узел

Символьные данные в начальном и конечном тегах узла элемента называются текстовыми узлами.

В примере кода узел элемента содержит название, а текстовый узел — «Гарри Поттер и узник Азкабана».

Harry Potter and the Prisoner of Azkaban

Узел пространства имен

В хорошо сформированных XML-документах используемым именам элементов и атрибутов присваивается пространство имен. Обычно это назначение происходит через определение типа документа в самом начале документа.

Если в элементе или атрибуте XML-документа используются различные пространства имен, то соответствующие пространства имен будут явно определены с помощью атрибута xmlns или префикса xmlns в начальном теге соответствующего элемента. Атрибут xmlns предполагает в качестве значения унифицированный идентификатор ресурса (URI), который указывает, какое пространство имен должно быть присвоено соответствующему элементу. Возможность присвоения пространства имен префиксу xmlns возможна для элемента или дочернего элемента. Каждому пространству имен соответствует узел пространства имен в древовидной структуре.

В примере кода для элемента XML address были определены два пространства имен: xmlns:shipping и xmlns:billing. Дочерние элементы элемента address несут соответствующее назначение в качестве префикса.

    <address xmlns:shipping="http://localhost/XML/delivery" xmlns:billing="http://localhost/XML/ billing">
        <shipping:name>Ellen Adams</shipping:name>
        <shipping:street>123 Maple Street</shipping:street>
        <shipping:city>Mill Valley</shipping:city>
        <shipping:state>CA</shipping:state>
        <shipping:zip>10999</shipping:zip>
        <shipping:country>USA</shipping:country>
        <billing:name>Mary Adams</billing:name>
        <billing:street>8 Oak Avenue</billing:street>
        <billing:city>Old Town</billing:city>
        <billing:state>PA</billing:state>
        <billing:zip>95819</billing:zip>
        <billing:country>USA</billing:country>
    </address>

Префикс xmlns позволяет четко назначить элементы с одинаковым именем из разных пространств имен. Например, элемент street с префиксом shipping содержит улицу, указанную в адресе доставки. Элемент street с префиксом billing, напротив, содержит улицу, указанную в адресе выставления счета.

Узел инструкции по обработке

Инструкции по обработке в XML-документах располагаются вне структуры дерева документа и в терминологии XPath называются узлом инструкции по обработке. Узел инструкции обработки начинается с <? и заканчивается ?>.

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

<!--?xml-stylesheet type="text/css" href="style.css"?-->

XML-декларация в начале XML-файла синтаксически построена как инструкция процесса. Однако оно не является действительным узлом инструкции процесса, как это определено в модели данных XPath.

Узел комментария

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

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

This is a comment!

Путь локализации

Обращение к узлам происходит с помощью пути локализации. С помощью путей локализации можно использовать выражение XPath для навигации по древовидной структуре и выбора нужного набора узлов. Набор узлов является результатом выражения XPath.

Пути локализации оцениваются слева направо. Различают абсолютные и относительные пути локализации. Абсолютный путь локализации начинается с узла документа. В этом случае в выражении XPath используется косая черта (/). Относительные пути локализации начинаются с произвольного узла в структуре дерева. Эта начальная точка называется контекстным узлом.

Путь локализации состоит из отдельных шагов локализации, которые, как и в случае обращения к файлам в системе каталогов, разделяются косой чертой (/).

Каждый шаг локализации состоит максимум из трех частей: оси, теста узла и произвольного количества предикатов.

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

Путь локализации для выражения XPath обозначается в соответствии со следующим синтаксисом:

axis::nodetest[predicate1][ predicate 2]…

Нотация

Функция

/

Функционирует как разделитель путей между двумя шагами локализации

::

Функционирует как разделитель путей между осью и тестом узла

Оси

Синтаксис XPath позволяет осуществлять навигацию с помощью следующих осей.

Ось

Выбранные узлы

дочерние

Все непосредственно подчиненные дочерние узлы

родительский

Непосредственно подчиненный родительский узел

потомок

Все подчиненные узлы

предок*

Все вышестоящие узлы

следующий

Все последующие узлы в последовательности документа, за исключением потомков

предшествующий*

Все предшествующие узлы в серии документов за исключением предков

следующий за родственным

Все последующие узлы в XML-документе, которые происходят от одного и того же родительского узла

предшествующий брат или сестра*

Все предшествующие узлы в XML-документе, которые происходят от одного и того же родительского узла

атрибут

Все узлы атрибутов для узла элемента

 

пространство имен

Все узлы пространства имен для узла элемента. Начиная с версии 2.0, эта ось больше не содержится в спецификации

self

Сам контекстный узел

descendant-or-self

Все подчиненные узлы, включая контекстный узел

предок или сам*

Все вышестоящие узлы, включая контекстный узел

Примечание

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

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

Например, все элементы child:: выбирают D из контекстного узла. Набор узлов состоит из узлов E, H и I.

Тест узла

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

  • Имя узла: укажите имя узла в качестве теста узла, чтобы выбрать все узлы с соответствующим именем на выбранной оси.
  • Тип узла: Укажите тип узла в качестве теста узла, чтобы выбрать все узлы на выбранной оси с соответствующим типом.

Имена узлов как критерий фильтрации

Например, при следующем пути локализации вы могли бы выбрать на основе примера кода, представленного выше, всех потомков с именем book, начиная с узла document.

/descendant::book

Однако если вы хотите отфильтровать атрибут isbn для всех узлов элементов с именем book, вам понадобится путь локализации с двумя шагами локализации.

/descendant::book/attribute::isbn

Тип узла как критерий фильтрации

Если вы хотите определить тип узла в качестве критерия фильтрации для выбора набора узлов, используйте одну из следующих функций в качестве теста узла:

Функция

Выбранные узлы

node()

Функция node() выбирает все узлы на выбранной оси.

text()

Функция text() выбирает все текстовые узлы на выбранной оси.

comment()

Функция comment() выбирает все узлы комментариев на выбранной оси.

инструкция обработки()

Функция processing-instruction() выбирает все узлы инструкции процесса на выбранной оси.

Примечание

В XPath 1.0 уже определено 25 функций. Начиная с XPath 2.0 для задания путей локализации доступно 111 функций. Обзор можно найти в рекомендации W3C XPath and XQuery functions and operators 3.1 от 21 марта 2017 года.

Проверка узла с помощью дикой карты

Если вместо теста узлов использовать символ * (звездочка), то на выбранной оси будут выбраны все узлы, соответствующие основному типу узлов оси. Таким образом, если ось содержит узлы элементов, то этот тип узла является основным типом узла оси. Это относится ко всем осям, за исключением осей атрибутов и пространств имен. В этом случае узлы атрибутов или узлы пространства имен квалифицируются как основные типы узлов.

Например, следующий путь локализации отображает все атрибуты текущего контекстного узла:

attribute::*

Сокращенная нотация

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

Стандартная нотация

Сокращение

Пример

ребенок::

blank

В случае с child речь идет о стандартной оси. При необходимости обозначение оси может быть опущено. Путь локализации child::book/child::title таким образом соответствует краткой аббревиатуре book/title.

атрибут::

@

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

Путь локализации book/attribute::isbn выбирает узел атрибута isbn элемента book и указывает book/@isbn в сокращенной нотации.

/descendant-or-self::node()/.

//

Шаг локализации /descendant-or-self::node()/ выбирает узел документа и всех потомков и сокращенно обозначается //.Вместо /descendant-or-self::node()/child::item пишем //item в сокращенной форме. Путь локализации выбирает все узлы элемента в документе.

parent::node()

..

Шаг локализации parent::node() выбирает родительский узел контекстного узла и сокращается с помощью .

self::node()

.

Шаг локализации self::node() выбирает текущий узел контекста и сокращается до .

Предикаты

С помощью предикатов вы определяете дополнительные критерии фильтрации для наборов узлов, выбранных с помощью проверки осей и узлов.

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

Синтаксис XPath поддерживает универсальные предикаты и числовые предикаты.

Универсальные предикаты

Выражения в универсальных предикатах фильтруют набор узлов, выбранных с помощью проверки осей и узлов, выдавая булево значение (true или false) для каждого узла в выборке. Все узлы со значением true входят в набор результатов.

Формулировка выражений для универсальных предикатов происходит с помощью операторов. Они используются для конкретного выбора узлов с определенным содержимым или свойствами — например, всех узлов, включающих символьную строку, значение атрибута или определенный дочерний элемент (возможно, в определенной позиции).

В следующих таблицах представлен обзор доступных операторов. Различают арифметические операторы, логические операторы и реляционные операторы.

Арифметические операторы

Функция

+

Сложение

Вычитание

*

Умножение

div

Разделитель с плавающей точкой

mod

Modulo

Реляционные операторы

Функция

=

Равно

!=

Неравный

<

Less than; требуется маскировка в XSLT (&lt;)

>

Больше, чем; маскировка в XSLT (&gt;) рекомендуется

<=

Меньше или равно; маскировка требуется в XSLT (&lt;)

>=

Больше или равно; рекомендуется маскировка в XSLT (&gt;)

Логические операторы

Функция

и

Логический и соединительный

или

Логический или соединительный

В следующем примере предикат изолирует [title=»Harry Potter and the Prisoner of Azkaban»] набор результатов на элементе nodecalled book, который содержит дочерний элемент title и строку Harry Potter and the Prisoner of Azkaban.

Примечание

Пример соответствует синтаксису XPath 3, который может не поддерживаться онлайн-инструментами. Воспроизведите представленный запрос, например, с помощью следующего онлайнового тестера: http://videlibri.sourceforge.net/cgi-bin/xidelcgi.

/order/items/book[title="Harry Potter and the Prisoner of Azkaban"] 

Теперь мы выбрали узел элемента book, который содержит данные для книги о Гарри Поттере.

        <book isbn="9781408845660">
            <title>Harry Potter and the Prisoner of Azkaban</title>
            <quantity>1</quantity>
            <priceus>22.94</priceus>
            <comment>Please confirm delivery date before Christmas.</comment>
        </book>

Другим дочерним элементом этого узла является элемент comment. Если мы хотим выбрать его содержимое, путь локализации должен быть расширен только на два шага локализации.

/order/items/book[title="Harry Potter and the Prisoner of Azkaban"]/comment/text()

С помощью шага локализации comment (сокращенная форма child::comment) мы переходим к одноименному дочернему элементу элемента book и выбираем его текстовый узел с помощью функции text(). Это соответствует следующей строке:

Please confirm delivery date before Christmas.

Если в предикате используется только выражение пути, то он называется тестом существования. С помощью следующего пути локализации, например, можно проверить, содержит ли представленный выше XML-документ один или несколько узлов с именем comment.

Сокращенная нотация:

//book[comment]

Стандартная нотация:

/descendant-or-self::node()/child::book[child::comment]

Путь локализации //book[comment] выбирает все узлы с именем book, которые имеют дочерний элемент с именем comment.

Числовые предикаты

Числовые предикаты позволяют обращаться к узлам, используя свою позицию. Например, следующий путь локализации выбирает второй узел в соответствии с последовательностью документов с именем book:

//book[2]

Строго говоря, предикат [2] — это сокращенная форма [position()=2]. Таким образом, XPath изначально выбирает все узлы с именем «book», а затем отфильтровывает узел, для которого функция position()=2 дает истинное булево значение.

Примечание

В отличие от языков программирования, нумерация в XPath начинается с 1.

Дополнительная информация о языке XML Path

На сайте W3C вы найдете обзор текущего состояния разработки языка XML Path, а также все выпущенные стандарты и проекты.

Бесплатная информация и инструменты для использования XPath в веб-приложениях доступны вам в MDN Web Docs, а также в Microsoft Developer Network.

Оцените статью
cdelat.ru
Добавить комментарий