Как написать xpath запрос
XPath = язык запросов к элементам XML или HTML документа, сиречь, ищет в таком документе нужное вам.
Так же как и SQL, XPath является декларативным языком запросов.
Чтобы получить интересующие данные, необходимо всего лишь создать запрос, описывающий эти данные. Всю «чёрную» работу за вас выполнит интерпретатор языка xpath.
Приоритет операций (от высокого к низкому) определяется следующим образом:
Очерёдность | Символ | Написание |
---|---|---|
1 | ( ) | Группирование |
2 | [ ] | Фильтры |
3 | / // | Операции с путями |
Операторы пути
С помощью операторов пути (/ и //) можно описать коллекцию элементов определенного типа. Эти операторы принимают в качестве аргументов коллекцию «с левой стороны», из которой производится выбор, и коллекцию «с правой стороны» как инструкцию, указывающую, какие элементы нужно выбирать. Оператор «дочерний элемент» (/) производит выбор из непосредственных дочерних элементов левой коллекции, в то время как оператор «потомок» (//) производит выбор из всех потомков коллекции левой стороны. Оператор // можно рассматривать как подстановку для одного или нескольких уровней иерархии.
Следует заметить, что операторы пути изменяют контекст по мере выполнения запроса. Соединив несколько операторов пути, можно просмотреть все дерево документа.
Символ-шаблон
Элемент можно использовать, не указывая его имя, с помощью коллекции символов-шаблонов (*). Коллекция* означает все элементы, являющиеся дочерними для текущего контекста, независимо от имени тега.
Атрибуты
В языке XPath имена атрибутов включают символ @. Атрибуты и дочерние элементы обрабатываются одинаково, и эти два типа считаются эквивалентными везде, где это возможно.
Атрибуты не могут содержать дочерних элементов, поэтому применение операторов пути к атрибутам порождает синтаксические ошибки. Кроме того, к атрибутам нельзя применять индексы, поскольку их порядок по определению не задан.
Примеры:
Выражение | Ссылается на |
---|---|
@style | Атрибут style контекста текущего элемента |
price/@exchange | Атрибут exchange элементов в текущем контексте |
book/@style | Атрибут style всех элементов |
Следующий пример содержит ошибку, поскольку у атрибута не может быть дочерних элементов: price/@exchange/total
Поиск нескольких атрибутов
Все атрибуты элемента можно получить с помощью метода @*. Это может быть полезно для приложений, рассматривающих атрибуты как поля записи.
Примеры работы с xPath
Описывать более подробно про язык xPath не имеет смысла, т.к. в интернете Вы найдете множество литературы на данную тему. Мне же хочется рассмотреть различные примеры работы с данным языком запросов.
Кстати, если Вы еще не поняли или не знали, то можно работать с HTML-документом как с объектом DOM. Например, недавно я писал парсер для своих нужд, который собирал некоторую информацию с сайта, далее ее сохранял в текстовые файлы.
Примечание. В PHP от версии 5 содержится класс DOMXPath (поддержка xPath 1.0), в котором как раз реализована работа с DOM.
Итак, перейдем к разбору примеров работы с xPath.
Это наши тестовые данные XML-документа.
Запрос: //book
Запрос: //book[2]
Если выполнить запрос как //book[last()], то вы получите только последний узел. В данном случае такой запрос аналогичен //book[3].
Запрос: //title/..
Запрос: //book/author[text() = «Каллум Хопкинс»]
Запрос: //book/content/rating[text() со значением меньше 5.
Запрос: magazine/*/price
Таким образом мы вернули все элементы
Примеров можно написать огромное множество. Я лишь показал часть возможностей по работе с xPath. В самом конце статьи прикрепляю полезные ссылки на ресурсы от Microsoft.
И наконец, для тех кто только начинает использовать xPath в своей работе будет не менее полезным Шпаргалка по xPath.
Полезные ссылки
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
XPATH + XML = быстрая обработка
При выполнении запросов язык XPath оперирует такими сущностями как узлы. Узлы бывают нескольких видов: element (узел-элемент), attribute (узел-атрибут), text (узел-текст), namespace (узел-пространство имён), processing-instruction (узел-исполняемая инструкция), comment (узел-комментарий), document (узел-документ).
Рассмотрим, как в XPATH задаётся последовательность узлов, направления выборки и выбирать узлы с конкретными значениями.
Для осуществления выборки узлов в основном используется 6 основных типов конструкций:
Так же при выборе узлов имеется возможность использовать wildcard маски, когда нам неизвестно, какой вид должен принимать узел.
В языке XPATH для выборки относительно текущего узла используются специальные конструкции под названием оси.
Правило выборки может быть как абсолютным (//input[@placeholder=”Логин” – выборка начиная с корневого узла], так и относительным (*@class=”okved-table__code” – выборка относительно текущего узла).
Построение правила выборки на каждом шаге выборки осуществляется относительно текущего узла и учитывает:
Для выборки конкретных узлов по некоторым условиям, параметрам или позиции используют такое инструментально средство как предикаты. Условие предиката ставится в квадратных скобках. Примеры:
Приведем такой практический пример. Нам необходимо выгрузить информацию о периодах определенного списка людей. Для этого воспользуемся сервисом notariat.ru.
Загружаем данные по людям:
Извлекаем информацию из страниц с информацией о людях.
Осуществляем поиск, используя модуль multiprocessing, для ускорения сбора данных.
И сохраняем результаты:
На рисунке ниже представлена страница поиска личных дел, на которой указываются ФИО, дата рождения, по которым в дальнейшем осуществляется поиск. После ввода ФИО и даты рождения алгоритм нажимает на кнопку искать дело, после чего анализирует полученные результаты.
На следующем рисунке видим список, парсингом элементов которого и занимается алгоритм.
На примере выше было показано, как можно использовать XPATH для сбора информации с веб-страниц. Но как уже было сказано, XPATH применим для обработки любых xml документов, являясь отраслевым стандартом для доступа к элементам xml и xhtml, xslt преобразований.
Зачастую читабельность кода влияет и на его качество, поэтому следует отказаться от регулярных выражений при парсинге, изучить XPATH и начать применять его в рабочем процессе. Это сделает ваш код проще, понятнее. Вы допустите меньше ошибок, а также сократиться время отладки.
Краткое руководство по XPath
XPath – это невероятно гибкий, мощный, и вместе с тем сравнительно простой инструмент для навигации по документам XML. Предлагаю перевод руководства по XPath, сделанный на основе руководства консорциума W3C.
Краткий справочник по XPath
XPath используется для навигации по элементам и атрибутам XML-документа. XPath является одним из основных элементов в стандарте XSLT консорциума W3C.
1 Что такое XPath
Выражения XPath
XPath использует выражения пути для выбора отдельных узлов или набора узлов в документе XML. Эти выражения очень похожи на выражения, которые вы видите, когда работаете с традиционной файловой системой компьютера.
Стандартные функции XPath
XPath включает в себя более 100 встроенных функций. Есть функции для строковых и числовых значений, даты и времени, сравнения узлов и манипулирования QName, управления последовательностями, булевых значений, и многое другое.
XPath используется в XSLT
XPath является одним из основных элементов в стандарте XSLT. Без знания XPath вы не будете иметь возможность создавать XSLT-документы.
XPath является рекомендацией консорциума W3C
XPath стал рекомендацией W3C 16 ноября 1999 года. XPath был разработан для использования в XSLT, XPointer и другом программном обеспечении для разбора (парсинга) документов XML.
2 Терминология XPath
В XPath существует семь видов узлов: элемент, атрибут, текст, пространство имён, инструкции обработки, комментарии и узлы документа. XML-документы обрабатываются в виде деревьев узлов. Верхний элемент дерева называется корневым элементом. Посмотрите на следующий документ XML:
Пример узлов в документе XML выше:
Атомарные значения
Атомарные значения являются узлами, не имеющие детей или родителей. Пример атомарных значений:
Элементы
Элементы – это атомарные значения или узлы.
3 Отношенияузлов
Родитель
Каждый элемент и атрибут имеет одного родителя. В следующем примере элемент «книга» (book) является родителем элементов «название» (title), «автор» (author), «год» (year) и «цена» (price):
Потомки
Узлы элементов могут иметь ноль, один или более потомков. В следующем примере элементы «название», «автор», «год» и «цена» – они все потомки элемента книга:
Элементы одного уровня
Это узлы, которые имеют одного и того же родителя. В следующем примере элементы «название», «автор», «год» и «цена» все являются элементами одного уровня:
Предки
Родитель узла, родитель родителя узла и т.д. В следующем примере предки элемента «название» (title) – это элементы «книга» (book) и «книжный магазин» (bookstore):
Потомки
Дети узла, дети детей узла и т.д. В следующем примере потомками элемента «книжный магазин» являются элементы «книга», «название», «автор», «год» и «цена»:
4 Синтаксис XPath
XPath использует выражения пути для выбора узлов или множества узлов в документе XML. Узел можно выбрать, следуя пути или по шагам. Мы будем использовать следующий XML-документ в приведённых ниже примерах.
Выбор узлов
С помощью выражений XPath для выбора узлов в документе XML можно выбрать узел, следуя пути или шагам. Самые полезные выражения пути перечислены ниже:
Выражение | Описание |
---|---|
имя_узла | Выбирает все узлы с именем имя_узла |
/ | Выбирает от корневого узла |
// | Выбирает узлы в документе от текущего узла, который соответствует выбору, независимо от того, где они находятся |
. | Выбирает текущий узел |
.. | Выбирает родителя текущего узла |
@ | Выбирает атрибуты |
В приведенной ниже таблице перечислены некоторые пути выражения и результат выполнения выражения:
Выражение XPath | Результат |
---|---|
bookstore | Выбирает все узлы с именем «bookstore» |
/bookstore | Выбирает корневой элемент книжного магазина Примечание: Если путь начинается с косой черты (/), он всегда представляет собой абсолютный путь к элементу! |
bookstore/book | Выбирает все элементы «книга» (book), которые являются потомками элемента «книжный магазин» (bookstore) |
//book | Выбирает все элементы «книга» независимо от того, где они находятся в документе |
bookstore//book | Выбирает все элементы «книга», которые являются потомком элемента «книжный магазин», независимо от того, где они находятся под элементом «книжный магазин» |
//@lang | Выбирает все атрибуты, которые называются «lang» |
Предикаты
Предикаты используются для поиска специфического узла или узла, который содержит специфическое значение. Предикаты всегда обрамляются квадратными скобками. В приведённой ниже таблице перечислены некоторые выражения пути с предикатами, и результат выражения:
Выражения XPath | Результат |
---|---|
/bookstore/book[1] | Выбирает первый элемент «книга», который является потомком элемента «книжный магазин». Примечание: В IE 5,6,7,8,9 первый узел имеет индекс [0], но в соответствии с рекомендациями W3C, это [1]. Для решения этой проблемы в IE, задаётся опция «SelectionLanguage» для XPath: На JavaScript: xml.setProperty(«SelectionLanguage», «XPath»); |
/bookstore/book[last()] | Выбирает последний элемент «книга» (book), который является дочерним элементом элемента «книжный магазин» (bookstore) |
/bookstore/book[last()-1] | Выбирает предпоследний элемент «книга», который является дочерним элементом элемента «книжный магазин» |
/bookstore/book[position() 35.00] | Выбирает все элементы «книга» после элемента «книжный магазин», которые имеют элемент «цена» со значением больше, чем 35.00 |
/bookstore/book[price>35.00]/title | Выбирает все элементы «название» книги элемента «книжный магазин», которые имеют элемент «цена» со значением больше, чем 35.00 |
Выбор неизвестных узлов
Специальные символы XPath могут использоваться для выбора неизвестных XML узлов.
Wildcard | Описание |
---|---|
* | Соответствует любому узлу |
@* | Соответствует узлу-атрибуту |
node() | Соответствует любому узлу любого типа |
В приведённой ниже таблице мы перечислили некоторые пути выражения и результаты выражений:
Выражение пути | Результат |
---|---|
/bookstore/* | Выбирает все дочерние узлы элемента «книжный магазин» (bookstore) |
//* | Выбирает все элементы в документе |
//title[@*] | Выбирает все элементы «название» (title), которые имеют по крайней мере один атрибут любого вида |
Выбор нескольких путей
С помощью оператора | в выражениях XPath вы можете выбрать несколько путей. В таблице ниже перечислены несколько выражений путей и результаты их применения:
Выражение пути | Результат |
---|---|
//book/title | //book/price | Выбирает все элементы «название» (title) И «цена» (price) всех элементов «книга» (book) |
//title | //price | Выбирает все элементы «название» (title) И «цена» (price) в документе |
/bookstore/book/title | //price | Выбирает все элементы «название» элемента «книга» элемента «книжный магазин» И все элементы «цена» в документе |
5 ОсиXPath
Мы будем использовать следующий XML документ далее в примере.
Оси определяют наборы узлов, относительно текущего узла.
Название оси | Результат |
---|---|
ancestor | Выбирает всех предков (родителей, прародителей и т.д.) текущего узла |
ancestor-or-self | Выбирает всех предков (родителей, прародителей и т.д.) текущего узла и сам текущий узел |
attribute | Выбирает все атрибуты текущего узла |
child | Выбирает всех потомков текущего узла |
descendant | Выбирает всех потомков (детей, внуков и т.д.) текущего узла |
descendant-or-self | Выбирает всех потомков (детей, внуков и т.д.) текущего узла и сам текущий узел |
following | Выбирает всё в документе после закрытия тэга текущего узла |
following-sibling | Выбирает все узлы одного уровня после текущего узла |
namespace | Выбирает все узлы в данном пространстве имён (namespace) текущего узла |
parent | Выбирает родителя текущего узла |
preceding | Выбирает все узлы, которые появляются перед текущим узлом в документе, за исключением предков, узлов атрибутов и узлы пространства имён |
preceding-sibling | Выбирает всех братьев и сестёр до текущего узла |
self | Выбирает текущий узел |
6 Выраженияпути выборки
Путь определения местоположения может быть абсолютным или относительным. Абсолютный путь расположения начинается с косой черты (/), а относительный – нет. В обоих случаях путь выборки состоит из одного или нескольких шагов, разделённых косой чертой:
Абсолютный путь расположения:
Относительный путь выборки расположения:
Каждый шаг оценивается по узлам в текущем наборе узлов. Шаг состоит из:
Синтаксис шага выборки такой:
Пример | Результат |
---|---|
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:
Давайте рассмотрим базовый синтаксис XPath на нескольких примерах. Мы будем использовать следующий XML документ «books.xml» в примерах ниже:
Загрузка XML документа
Используйте XMLHttpRequest для загрузки XML документов, который поддерживается большинством современных браузеров:
Код для устаревших браузеров Microsoft (IE 5 и 6):
Выбор узлов
К сожалению, работа с XPath в Internet Explorer и в других браузерах может отличаться. В наших примерах мы будем использовать код, который должен работать в большинстве браузеров. Internet Explorer использует метод «selectNodes()» для выбора узлов XML документа:
Firefox, Chrome, Opera и Safari используют метод evaluate() для выбора узлов из XML документа:
Выбор всех заглавий
Следующий пример выбирает все узлы заголовков:
Выбор заголовка первой книги
Следующий пример выбирает заголовок первого узла «книга» после элемента «книжный магазин» (bookstore):
Выбор всех цен
Следующий пример выбирает текст всех узлов «цена» (price):
Выбирает узлы с ценой >35
Следующий пример выбирает все узлы с ценами выше 35:
Выбор узлов заголовков с ценой >35
Следующий пример выбирает все узлы заголовков с ценой выше 35:
Синтаксис XPath
Для выбора узлов и наборов узлов в XML документе XPath использует выражения путей. Узел выбирается следуя по заданному пути или по, так называемым, шагам.
Пример XML документа
Для демонстрации синтаксиса XPath будет использоваться следующий XML документ:
Выбор узлов
Чтобы выбрать узлы в XML документе, XPath использует выражения пути. Узел выбирается следуя по заданному пути. Наиболее полезные выражения пути:
Выражение | Результат |
---|---|
имя_узла | Выбирает все узлы с именем «имя_узла» |
/ | Выбирает от корневого узла |
// | Выбирает узлы от текущего узла, соответствующего выбору, независимо от их местонахождения |
. | Выбирает текущий узел |
.. | Выбирает родителя текущего узла |
@ | Выбирает атрибуты |
В следующей таблице приводятся некоторые выражения XPath, позволяющие сделать некоторые выборки по демонстрационному XML документу:
Выражение XPath | Результат |
---|---|
messages | Выбирает все узлы с именем «messages» |
/messages | Выбирает корневой элемент сообщений Примечание: Если путь начинается с косой черты ( / ), то он всегда представляет абсолютный путь к элементу! |
messages/note | Выбирает все элементы note, являющиеся потомками элемента messages |
//note | Выбирает все элементы note независимо от того, где в документе они находятся |
messages//note | Выбирает все элементы note, являющиеся потомками элемента messages независимо от того, где они находятся от элемента messages |
//@date | Выбирает все атрибуты с именем date |
Предикаты
Предикаты позволяют найти конкретный узел или узел с конкретным значением.
Предикаты всегда заключаются в квадратные скобки.
В следующей таблице приводятся некоторые выражения XPath с предикатами, позволяющие сделать выборки по демонстрационному XML документу: