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:
Пример узлов в документе XML выше:
Атомарные значения
Атомарные значения являются узлами, не имеющие детей или родителей. Пример атомарных значений:
J. K. Rowling "en"
Элементы
Элементы - это атомарные значения или узлы.
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 | Выбирает первый элемент «книга», который является потомком элемента «книжный магазин».
Примечание: В 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 документ далее в примере.
Оси определяют наборы узлов, относительно текущего узла.
Название оси | Результат |
---|---|
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 |
< | Меньше, чем | price<9.80 |
<= | Меньше или равно | price≤9.80 |
> | Больше, чем | price>9.80 |
>= | Больше или равно | price≤9.80 |
or | Или | price=9.80 or price=9.70 |
and | И | price>9.00 and price<9.90 |
mod | Остаток от деления | 5 mod 2 |
8 Примеры XPath
Давайте рассмотрим базовый синтаксис XPath на нескольких примерах. Мы будем использовать следующий XML документ "books.xml" в примерах ниже:
Загрузка XML документа
Используйте XMLHttpRequest для загрузки XML документов, который поддерживается большинством современных браузеров:
Var xmlhttp=new XMLHttpRequest()
Код для устаревших браузеров Microsoft (IE 5 и 6):
Var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
Выбор узлов
К сожалению, работа с XPath в Internet Explorer и в других браузерах может отличаться. В наших примерах мы будем использовать код, который должен работать в большинстве браузеров. Internet Explorer использует метод "selectNodes()" для выбора узлов XML документа:
XmlDoc.selectNodes(xpath);
Firefox, Chrome, Opera и Safari используют метод evaluate() для выбора узлов из XML документа:
XmlDoc.evaluate(xpath, xmlDoc, null, XPathResult.ANY_TYPE, null);
Выбор всех заглавий
Следующий пример выбирает все узлы заголовков:
/bookstore/book/title
Выбор заголовка первой книги
Следующий пример выбирает заголовок первого узла «книга» после элемента «книжный магазин» (bookstore):
/bookstore/book/title
Выбор всех цен
Следующий пример выбирает текст всех узлов «цена» (price):
/bookstore/book/price
Выбирает узлы с ценой >35
Следующий пример выбирает все узлы с ценами выше 35:
/bookstore/book/price
Выбор узлов заголовков с ценой >35
Следующий пример выбирает все узлы заголовков с ценой выше 35:
/bookstore/book/title
Примеры использования xpath из практики парсинга информации с сайтов. Приведены участки кода xpath.
Получить текст заголовока h1
//h1/text()
Получить текст заголовока с классом produnctName
//h1[@class="produnctName"]/text()
Получить значение определенного span по классу
//span[@class="price"]
Получить значение атрибута title у кнопки с классом addtocart_button
//input[@class="addtocart_button"]/@title
//a/text()
//a/@href
Изображение src
//img/@src
Изображение сразу за определенным элементом в DOM, ось following
//h1[@class="produnctName"]//following::div/img/@src
Изображение в 4 div по счету
//div/img/@src
XPath (XML Path Language) — язык запросов к элементам XML-документа. Разработан для организации доступа к частям документа XML в файлах трансформации XSLT и является стандартом консорциума W3C. XPath призван реализовать навигацию по DOM в XML.
XML имеет древовидную структуру. У элемента дерева всегда существуют потомки и предки, кроме корневого элемента, у которого предков нет, а также тупиковых элементов (листьев дерева), у которых нет потомков.
На каждом шаге пути отбираются элементы, соответствующие условиям отбора на этом шаге, и в результате обращения по пути к документу получается множество элементов, удовлетворяющих данному пути.
Функции над множествами узлов
- * — обозначает любое имя или набор символов по указанной оси, например: * — любой дочерний узел; @* — любой атрибут.
- $name — обращение к переменной, где name — имя переменной или параметра.
- — дополнительные условия выборки или, что то же самое, предикат шага адресации. Должен содержать логическое значение. Если содержит числовое, считается что это порядковый номер узла, что эквивалентно приписыванию перед этим числом выражения «position()=»
- {} — если применяется внутри тега другого языка (например HTML), то XSLT процессор рассматривает содержимое фигурных скобок как XPath.
- / — определяет уровень дерева, то есть разделяет шаги адресации
- | — объединяет результат. То есть, можно написать несколько путей разбора через знак | и в результат такого выражения войдёт всё, что будет найдено любым из этих путей.
- node-set node ()
Возвращает все узлы. Вместо этой функции часто используют заменитель "*", но, в отличие от звездочки, функция node() возвращает и текстовые узлы.
- string text ()
Возвращает набор текстовых узлов;
- node-set current ()
Возвращает множество из одного элемента, который является текущим. Если мы делаем обработку множества с условиями, то единственным способом дотянуться из этого условия до текущего элемента будет данная функция.
- number position ()
Возвращает позицию элемента в множестве. Корректно работает только в цикле
- number last ()
Возвращает номер последнего элемента в множестве. Корректно работает только в цикле
- number count (node-set)
Возвращает количество элементов в node-set.
- string name (node-set?)
Возвращает полное имя первого тега в множестве.
- string namespace-uri (node-set?)
- string local-name (node-set?)
Возвращает имя первого тега в множестве, без пространства имён.
- node-set id (object)
Находит элемент с уникальным идентификатором
Оси — это база языка XPath. Для некоторых осей существуют сокращённые обозначения.
- ancestor:: — Возвращает множество предков.
- ancestor-or-self:: — Возвращает множество предков и текущий элемент.
- attribute:: — Возвращает множество атрибутов текущего элемента. Это обращение можно заменить на «@»
- child:: — Возвращает множество потомков на один уровень ниже. Это название сокращается полностью, то есть его можно вовсе опускать.
- descendant:: — Возвращает полное множество потомков (то есть, как ближайших потомков, так и всех их потомков).
- descendant-or-self:: — Возвращает полное множество потомков и текущий элемент. Выражение «/descendant-or-self::node()/» можно сокращать до «//» . С помощью этой оси, например, можно вторым шагом организовать отбор элементов с любого узла, а не только с корневого: достаточно первым шагом взять всех потомков корневого. Например, путь «//span» отберёт все узлы span документа, независимо от их положения в иерархии, взглянув как на имя корневого, так и на имена всех его дочерних элементов, на всю глубину их вложенности.
- following:: — Возвращает необработанное множество, ниже текущего элемента.
- following-sibling:: — Возвращает множество элементов на том же уровне, следующих за текущим.
- namespace:: — Возвращает множество, имеющее пространство имён (то есть присутствует атрибут xmlns).
- parent:: — Возвращает предка на один уровень назад. Это обращение можно заменить на «..»
- preceding:: — Возвращает множество обработанных элементов исключая множество предков.
- preceding-sibling:: — Возвращает множество элементов на том же уровне, предшествующих текущему.
- self:: — Возвращает текущий элемент. Это обращение можно заменить на «.»
XPath использует выражения пути для выбора узлов в документе XML или набор узлов. По узлу вдоль пути (путь) или стадии (шагов) к выбранному.
экземпляра XML-документы
Мы будем использовать этот XML-документ в приведенных ниже примерах.
Выберите узел
XPath использует выражения пути для выбора узлов в документе XML. Или по пути через узел для выбора шага. Ниже перечислены наиболее полезные выражения пути:
В приведенной ниже таблице мы приводим некоторые из путей выражения и результат выражения:
выражение Путь | результат |
---|---|
книжный магазин | Выберите все дочерние узлы книжного элемента. |
/ Книжный магазин | Выберите корневой элемент книжный магазин. Примечание: Если путь начинается с косой черты (/), путь всегда представитель абсолютного пути к элементу! |
книжный магазин / книга | Выберите вложенные элементы, принадлежащие в книжном магазине все книжные элементы. |
// Книга | Выделить все книги подэлементы, независимо от их положения в документе. |
книжный магазин // книга | Выбирает все книжные элементы, которые не принадлежат к потомкам книжного магазина элемента, независимо от того, в каком положении они находятся в и под книжный магазин. |
// @ Lang | Выберите все свойства названных Ланг. |
Предикат (Предикаты)
Предикат используется, чтобы найти конкретный узел или узел, который содержит значение, указанное.
Предикат вкладывается в квадратные скобки.
В приведенной ниже таблице, мы перечислили некоторые выражения пути с предикатами и результат выражения:
выражение Путь | результат |
---|---|
/ Книжный магазин / книга | Выберите вложенные элементы, принадлежащие первой книги книжный элемент. |
/ Книжный магазин / книга [последняя ()] | Выберите вложенные элементы, принадлежащие книжный последний книжный элемент. |
/ Книжный магазин / книга [последняя () - 1] | Выберите вложенные элементы, относящиеся к взаимным книжного магазина второго книжного элемента. |
/ Книжный магазин / книга [положение () <3] | Выберите первые две книги элементы книжного элемента, принадлежащего к подэлементов. |
// Название [@lang] | Выбрать все атрибут с именем Ланг имеет заголовок элемента. |
// Заголовок [@ LANG = "анг"] | Выделите все названия элементов, и эти элементы имеют значение атрибута англ яз. |
/bookstore/book | Выделить все книжные элементы книжного элемента, а значение ценового элемента, который должен быть больше, чем 35.00. |
/bookstore/book/title | Выберите все элементы заголовка книги элементов книжного элемента, и в котором значение ценового элемента должно быть больше, чем 35.00. |
Выберите неизвестные узлы
XPath групповые символы могут быть использованы для выбора неизвестных элементов XML.
В приведенной ниже таблице, мы перечислили некоторые выражения пути, а также результаты этих выражений:
Выберите несколько путей
Используя выражение пути "|" оператора, вы можете выбрать несколько путей.
В приведенной ниже таблице, мы перечислили некоторые выражения пути, а также результаты этих выражений.
Сокращенный синтаксис XPath
Сокращения синтаксиса XPath могут быть весьма удобными. Ниже приведены правила:
Self::node() может быть сокращено как. ;
Parent::node() может быть сокращено как.. ;
Child::childname может быть сокращено как childname ;
Attribute::childname может быть сокращено как @childname ;
/descendant-or-self::node()/ может быть сокращено как // .
Например, путь расположения.//PLANET - сокращение для self::node()/descendant-or-self::node()/child::PLANET . Можно также сократить выражение предиката как , как и т.д. Работать с путями расположения XPath при помощи сокращенного синтаксиса значительно проще. В следующем списке перечислен ряд примеров путей расположения с использованием сокращенного синтаксиса:
PLANET возвращает дочерние элементы
* возвращает все дочерние элементы контекстного узла;
Text() возвращает все дочерние текстовые узлы контекстного узла;
@UNITS возвращает атрибут UNITS контекстного узла;
@* возвращает все атрибуты контекстного узла;
PLANET возвращает третьего ребенка
PLANET возвращает последнего ребенка
*/PLANET возвращает всех внуков
/PLANETS/PLANET/NAME возвращает второй элемент //PLANET возвращает всех потомков PLANETS//PLANET возвращает элементы-потомки //PLANET/NAME возвращает все элементы Возвращает сам контекстный узел; .//PLANET возвращает элементы-потомки Возвращает родителя контекстного узла; ../@UNITS возвращает атрибут UNITS родителя контекстного узла; .//.. возвращает всех родителей потомка контекстного узла и родителя контекстного узла; PLANET возвращает детей PLANET возвращает детей PLANET[@UNITS="days"] возвращает всех детей PLANET[@UNITS="days"] возвращает шестого ребенка PLANET[@COLOR and @UNITS] возвращает всех детей " //PLANET " выбирает все элементы * выбирает любой элемент *[@UNITS] выбирает первых пятерых детей контекстного узла, у которых есть атрибут UNITS . Сокращенный синтаксис
Для образцов существует два правила сокращения осей: child::childname может быть сокращено как childname; attribute::childname может быть сокращено как @childname.В следующем списке перечислен ряд примеров образцов с сокращенным синтаксисом; в конце главы вы увидите Сокращенный синтаксис предикатов
Выражения предикатов можно сокращать, опуская "position()=". Например, становится , становится и т.д. С использованием сокращенного синтаксиса применять выражения XPath в предикатах становится существенно проще. Вот ряд Числа XPath
В XPath числа хранятся в формате чисел с плавающей точкой двойной точности. В соответствии с формальным определением, числа XPath должны храниться в формате 64-разрядных чисел с плавающей точкой двойной точности IEEE 754, и все числа хранятся как числа с плавающей точкой Применение осей XPath
К этому моменту мы рассмотрели три части шагов расположения - ось, условие узла и предикат. Вы должны быть знакомы с этими элементами по проделанной нами работе с образцами выбора, но обратите внимание на ось в предыдущем примере - preceding-sibling. До сих пор Проверка выражений XPath
В пакет Xalan входит удобная программа-пример, ApplyXPath.java, позволяющая применить выражение XPath к документу и посмотреть на результат, что очень помогает при тестировании. Для запуска этого примера вам нужно будет скомпилировать ApplyXPath.java в ApplyXPath.class при