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 version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="en">Harry Potter</title>
<author>J. K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
Пример узлов в документе XML выше:
<bookstore> (корневой элемент) <author>J. K. Rowling</author> (узел) lang="en" (атрибут)
Атомарные значения
Атомарные значения являются узлами, не имеющие детей или родителей. Пример атомарных значений:
J. K. Rowling "en"
Элементы
Элементы – это атомарные значения или узлы.
3Отношенияузлов
Родитель
Каждый элемент и атрибут имеет одного родителя. В следующем примере элемент «книга» (book) является родителем элементов «название» (title), «автор» (author), «год» (year) и «цена» (price):
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
Потомки
Узлы элементов могут иметь ноль, один или более потомков. В следующем примере элементы «название», «автор», «год» и «цена» – они все потомки элемента книга:
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
Элементы одного уровня
Это узлы, которые имеют одного и того же родителя. В следующем примере элементы «название», «автор», «год» и «цена» все являются элементами одного уровня:
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
Предки
Родитель узла, родитель родителя узла и т.д. В следующем примере предки элемента «название» (title) – это элементы «книга» (book) и «книжный магазин» (bookstore):
<bookstore>
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
Потомки
Дети узла, дети детей узла и т.д. В следующем примере потомками элемента «книжный магазин» являются элементы «книга», «название», «автор», «год» и «цена»:
<bookstore>
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
4Синтаксис XPath
XPath использует выражения пути для выбора узлов или множества узлов в документе XML. Узел можно выбрать, следуя пути или по шагам. Мы будем использовать следующий XML-документ в приведённых ниже примерах.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="en">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="en">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
Выбор узлов
С помощью выражений 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()<3] | Выбор первых двух элементов «книга», которые являются потомками элемента «книжный магазин» |
| //title[@lang] | Выбирает все элементы «название» (title), которые имеют атрибут с именем «lang» |
| //title[@lang=’en’] | Выбирает все элементы «название», которые имеют атрибут «язык» со значением «en» |
| /bookstore/book[price>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 документ далее в примере.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="en">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="en">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
Оси определяют наборы узлов, относительно текущего узла.
| Название оси | Результат |
|---|---|
| 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[predicate] имяОси::проверкаУзла[предиктор]
| Пример | Результат |
|---|---|
| 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 version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
Загрузка 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[1]/title
Выбор всех цен
Следующий пример выбирает текст всех узлов «цена» (price):
/bookstore/book/price[text()]
Выбирает узлы с ценой >35
Следующий пример выбирает все узлы с ценами выше 35:
/bookstore/book[price>35]/price
Выбор узлов заголовков с ценой >35
Следующий пример выбирает все узлы заголовков с ценой выше 35:
/bookstore/book[price>35]/title
Для отладки XPath удобно пользоваться специальными инструментами. Например, в IDE Stylus Studio или в Altova XMLSpy имеется генератор и отладчик XPath. Также есть бесплатные онлайн-инструменты для отладки XPath: XPather или CodeBeautify и другие.
XPath – Обзор
Прежде чем изучать XPath, мы должны сначала понять XSL, который расшифровывается как L Расширяемая таблица типов. Это похоже на XML, как CSS на HTML.
Нужен для XSL
В случае документов HTML предварительно определены теги, такие как таблица, div, span и т. Д. Браузер знает, как добавить к ним стиль и отобразить их с помощью стилей CSS. Но в случае документов XML теги не предопределены. Чтобы понять и оформить XML-документ, Консорциум World Wide Web (W3C) разработал XSL, который может выступать в качестве языка таблиц стилей на основе XML. Документ XSL определяет, как браузер должен отображать документ XML.
Ниже приведены основные части XSL –
-
XSLT – используется для преобразования документов XML в различные другие типы документов.
-
XPath – используется для навигации по документам XML.
-
XSL-FO – используется для форматирования документов XML.
XSLT – используется для преобразования документов XML в различные другие типы документов.
XPath – используется для навигации по документам XML.
XSL-FO – используется для форматирования документов XML.
Что такое XPath?
XPath является официальной рекомендацией Консорциума World Wide Web (W3C). Он определяет язык для поиска информации в файле XML. Он используется для обхода элементов и атрибутов XML-документа. XPath предоставляет различные типы выражений, которые можно использовать для запроса соответствующей информации из документа XML.
-
Определения структуры – XPath определяет части документа XML, такие как элемент, атрибут, текст, пространство имен, инструкция обработки, комментарий и узлы документа.
-
Выражения пути – XPath предоставляет мощные выражения пути для выбора узлов или списка узлов в документах XML.
-
Стандартные функции – XPath предоставляет богатую библиотеку стандартных функций для манипулирования строковыми значениями, числовыми значениями, сравнения даты и времени, манипулирования узлами и QName, манипулирования последовательностями, логическими значениями и т. Д.
-
Основная часть XSLT – XPath является одним из основных элементов в стандарте XSLT и должен обладать знаниями для работы с документами XSLT.
-
Рекомендация W3C – XPath является официальной рекомендацией Консорциума World Wide Web (W3C).
Определения структуры – XPath определяет части документа XML, такие как элемент, атрибут, текст, пространство имен, инструкция обработки, комментарий и узлы документа.
Выражения пути – XPath предоставляет мощные выражения пути для выбора узлов или списка узлов в документах XML.
Стандартные функции – XPath предоставляет богатую библиотеку стандартных функций для манипулирования строковыми значениями, числовыми значениями, сравнения даты и времени, манипулирования узлами и QName, манипулирования последовательностями, логическими значениями и т. Д.
Основная часть XSLT – XPath является одним из основных элементов в стандарте XSLT и должен обладать знаниями для работы с документами XSLT.
Рекомендация W3C – XPath является официальной рекомендацией Консорциума World Wide Web (W3C).
При работе с XPath необходимо учитывать следующие моменты:
- XPath является основным компонентом стандарта XSLT .
- XSLT не может работать без XPath.
- XPath является основой XQuery и XPointer.
XPath – Выражение
Выражение XPath обычно определяет шаблон для выбора набора узлов. Эти шаблоны используются XSLT для выполнения преобразований или XPointer для целей адресации.
Спецификация XPath определяет семь типов узлов, которые могут быть результатом выполнения выражения XPath.
- корень
- Элемент
- Текст
- атрибут
- Комментарий
- Инструкция по обработке
- Пространство имен
XPath использует выражение пути для выбора узла или списка узлов в документе XML.
Ниже приведен список полезных путей и выражений для выбора любого узла / списка узлов из XML-документа.
| S.No. | Выражение и описание |
|---|---|
| 1 |
имя-узла Выберите все узлы с заданным именем «nodename» |
| 2 |
/ Выбор начинается с корневого узла |
| 3 |
// Выбор начинается с текущего узла, соответствующего выбору |
| 4 |
, Выбирает текущий узел |
| 5 |
.. Выбирает родителя текущего узла |
| 6 |
@ Выбирает атрибуты |
| 7 |
ученик Пример – выбираются все узлы с именем «студент» |
| 8 |
класс / студент Пример – выбираются все элементы ученика, которые являются потомками класса |
| 9 |
//ученик Выбирает все элементы ученика независимо от того, где они находятся в документе |
имя-узла
Выберите все узлы с заданным именем «nodename»
/
Выбор начинается с корневого узла
//
Выбор начинается с текущего узла, соответствующего выбору
,
Выбирает текущий узел
..
Выбирает родителя текущего узла
@
Выбирает атрибуты
ученик
Пример – выбираются все узлы с именем «студент»
класс / студент
Пример – выбираются все элементы ученика, которые являются потомками класса
//ученик
Выбирает все элементы ученика независимо от того, где они находятся в документе
пример
В этом примере мы создали образец XML-документа Students.xml и его таблицы стилей student.xsl, в котором используются выражения XPath в атрибуте select различных тегов XSL для получения значений roll no, firstname, lastname, псевдонима и меток. каждого студенческого узла.
students.xml
<?xml version = "1.0"?> <?xml-stylesheet type = "text/xsl" href = "students.xsl"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vaneet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Students</h2>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<xsl:for-each select = "class/student">
<tr>
<td> <xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Проверьте вывод
XPath – узлы
В этой главе мы подробно рассмотрим выражение XPath, охватывающее распространенные типы узлов, которые определяет и обрабатывает XPath.
| S.No. | Тип и описание узла |
|---|---|
| 1 | корень
Узел корневого элемента XML-документа. |
| 2 | Элемент
Элемент узла. |
| 3 | Текст
Текст элемента узла. |
| 4 | атрибут
Атрибут элемента узла. |
| 5 | Комментарий
Комментарий |
Узел корневого элемента XML-документа.
Элемент узла.
Текст элемента узла.
Атрибут элемента узла.
Комментарий
XPath – Абсолютный Путь
Путь расположения указывает местоположение узла в документе XML. Этот путь может быть абсолютным или относительным. Если путь к местоположению начинается с корневого узла или с ‘/’, то это абсолютный путь. Ниже приведены несколько примеров размещения элементов по абсолютному пути.
/ class / student – выбрать студенческие узлы в корневом узле класса.
<xsl:for-each select = "/class/student">
/ class / student / firstname – выберите имя студенческого узла внутри корневого узла класса.
<p><xsl:value-of select = "/class/student/firstname"/></p>
пример
В этом примере мы создали образец XML-документа student.xml и его документ таблицы стилей student.xsl, в котором используются выражения XPath.
Ниже приведен пример используемого XML.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/" >
<html>
<body>
<h3>Details of each Students. </h3>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<tr>
<td><xsl:value-of select = "/class/student[1]/@rollno"/></td>
<td><xsl:value-of select = "/class/student[1]/firstname"/></td>
<td><xsl:value-of select = "/class/student[1]/lastname"/></td>
<td><xsl:value-of select = "/class/student[1]/nickname"/></td>
<td><xsl:value-of select = "/class/student[1]/marks"/></td>
</tr>
<tr>
<td>
<xsl:value-of select = "/class/student/@rollno"/>
</td>
<td><xsl:value-of select = "/class/student[2]/firstname"/></td>
<td><xsl:value-of select = "/class/student[2]/lastname"/></td>
<td><xsl:value-of select = "/class/student[2]/nickname"/></td>
<td><xsl:value-of select = "/class/student[2]/marks"/></td>
</tr>
<tr>
<td>
<xsl:value-of select = "/class/student[3]/@rollno"/>
</td>
<td><xsl:value-of select = "/class/student[3]/firstname"/></td>
<td><xsl:value-of select = "/class/student[3]/lastname"/></td>
<td><xsl:value-of select = "/class/student[3]/nickname"/></td>
<td><xsl:value-of select = "/class/student[3]/marks"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Проверьте вывод
XPath – относительный путь
Путь расположения указывает местоположение узла в документе XML. Этот путь может быть абсолютным или относительным. Если путь к местоположению начинается с выбранного нами узла, то это относительный путь.
Ниже приведено несколько примеров размещения элементов с использованием относительного пути.
Имя – выберите имя, связанное с узлами ученика.
<p><xsl:value-of select = "firstname"/></p>
пример
В этом примере мы создали образец XML-документа student.xml и его документ таблицы стилей student.xsl, в котором используются выражения XPath.
Ниже приведен пример используемого XML.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/" >
<html>
<body>
<h3>Details of each Students. </h3>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<xsl:for-each select = "/class/student">
<tr>
<td><xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Проверьте вывод
XPath – Оси
Поскольку путь местоположения определяет местоположение узла, используя абсолютный или относительный путь, оси используются для идентификации элементов по их отношениям, таким как родитель, дочерний элемент , родной брат и т. Д. Оси названы так, потому что они относятся к оси, на которой элементы лежат относительно элемент.
Ниже приведен список различных значений оси.
| S.No. | Ось и описание |
|---|---|
| 1 |
предок Представляет предков текущего узла, которые включают родителей до корневого узла. |
| 2 |
предок или-я Представляет текущий узел и его предков. |
| 3 |
атрибут Представляет атрибуты текущего узла. |
| 4 |
ребенок Представляет дочерние элементы текущего узла. |
| 5 |
потомок Представляет потомков текущего узла. Потомки включают дочерние узлы до конечного узла (не более дочерних). |
| 6 |
потомок или-я Представляет текущий узел и его потомков. |
| 7 |
следующий Представляет все узлы, которые идут после текущего узла. |
| 8 |
следующая-родственный Представляет следующие элементы узла контекста. Братья и сестры находятся на том же уровне, что и текущий узел, и совместно используют его родителя. |
| 9 |
Пространство имен Представляет пространство имен текущего узла. |
| 10 |
родитель Представляет родителя текущего узла. |
| 11 |
предшествующий Представляет все узлы, которые идут перед текущим узлом (т. Е. Перед его открывающим тегом). |
| 12 |
сам Представляет текущий узел. |
предок
Представляет предков текущего узла, которые включают родителей до корневого узла.
предок или-я
Представляет текущий узел и его предков.
атрибут
Представляет атрибуты текущего узла.
ребенок
Представляет дочерние элементы текущего узла.
потомок
Представляет потомков текущего узла. Потомки включают дочерние узлы до конечного узла (не более дочерних).
потомок или-я
Представляет текущий узел и его потомков.
следующий
Представляет все узлы, которые идут после текущего узла.
следующая-родственный
Представляет следующие элементы узла контекста. Братья и сестры находятся на том же уровне, что и текущий узел, и совместно используют его родителя.
Пространство имен
Представляет пространство имен текущего узла.
родитель
Представляет родителя текущего узла.
предшествующий
Представляет все узлы, которые идут перед текущим узлом (т. Е. Перед его открывающим тегом).
сам
Представляет текущий узел.
Ниже приведены несколько примеров использования осей.
Имя – выберите имя, связанное с узлами ученика.
<p><xsl:value-of select = "firstname"/></p> <xsl:value-of select = "/class/student/preceding-sibling::comment()"/>
пример
В этом примере мы создали образец XML-документа student.xml и его документ таблицы стилей student.xsl, в котором используются выражения XPath.
Ниже приведен пример используемого XML.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<!-- Comment: This is a list of student -->
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/" >
<html>
<body>
<xsl:value-of select = "/class/student/preceding-sibling::comment()"/>
<br/>
<xsl:text>First Student: </xsl:text>
<xsl:value-of select = "/class/student/child::firstname" />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Проверьте вывод
XPath – Операторы
В этой главе мы подробно рассмотрим операторы и функции XPath, охватывающие часто используемые определения и дескрипторы XPath. XPath определяет операторы и функции для типов Nodes, String, Number и Boolean.
Ниже приведен список, о котором мы собираемся обсудить.
| S.No. | Операторы / Функции и Описание |
|---|---|
| 1 | Операторы сравнения
Операторы сравнения для сравнения значений. |
| 2 | Булевы операторы
Булевы операторы для проверки функциональности ‘и’, ‘или’ & ‘not’. |
| 3 | Числовые функции / операторы
Операторы / Функции по номерам. |
| 4 | Строковые функции
Различные строковые функции. |
| 5 | Узел Функции / Операторы
Различные функции и операторы, действующие на узлы. |
Операторы сравнения для сравнения значений.
Булевы операторы для проверки функциональности ‘и’, ‘или’ & ‘not’.
Операторы / Функции по номерам.
Различные строковые функции.
Различные функции и операторы, действующие на узлы.
XPath – подстановочный знак
XPath определяет следующие подстановочные знаки на узлах, которые будут использоваться с выражениями XPath.
| S.No. | WildCard и описание |
|---|---|
| 1 |
* используется для сопоставления с любым узлом. |
| 2 |
, используется для сопоставления текущего узла в контексте. |
| 3 |
@ * используется для соответствия любому атрибуту |
| 4 |
узел() используется для сопоставления узла любого типа |
*
используется для сопоставления с любым узлом.
,
используется для сопоставления текущего узла в контексте.
@ *
используется для соответствия любому атрибуту
узел()
используется для сопоставления узла любого типа
пример
В этом примере создается таблица элемента <student> с их деталями путем итерации по каждому студенту.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Students</h2>
<xsl:apply-templates select = "class/*" />
</body>
</html>
</xsl:template>
<xsl:template match = "class/*">
<xsl:apply-templates select = "@rollno" />
<xsl:apply-templates select = "firstname" />
<xsl:apply-templates select = "lastname" />
<xsl:apply-templates select = "nickname" />
<xsl:apply-templates select = "marks" />
<br />
</xsl:template>
<xsl:template match = "@rollno">
<span style = "font-size = 22px;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "firstname">
First Name:<span style = "color:blue;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "lastname">
Last Name:<span style = "color:green;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "nickname">
Nick Name:<span style = "color:red;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "marks">
Marks:<span style = "color:gray;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
</xsl:stylesheet>
Проверьте вывод
XPath – предикат
Предикат относится к выражению XPath, написанному в квадратных скобках. Это относится к ограничению выбранных узлов в наборе узлов для некоторого условия. Например,
| S.No. | Предикат и описание |
|---|---|
| 1 |
/ класс / студент [1] Выберите первый элемент ученика, который является дочерним элементом элемента класса. |
| 2 |
/ класс / студент [последняя ()] Выберите последний элемент студента, который является дочерним элементом элемента класса. |
| 3 |
/ класс / студент [@rolllno = 493] Выберите элемент «студент» с помощью rollno 493. |
| 4 |
/ класс / студент [знаки> 85] Выберите элемент ученика с отметками> 85. |
/ класс / студент [1]
Выберите первый элемент ученика, который является дочерним элементом элемента класса.
/ класс / студент [последняя ()]
Выберите последний элемент студента, который является дочерним элементом элемента класса.
/ класс / студент [@rolllno = 493]
Выберите элемент «студент» с помощью rollno 493.
/ класс / студент [знаки> 85]
Выберите элемент ученика с отметками> 85.
пример
В этом примере создается таблица элемента <student> с их деталями путем итерации по каждому студенту. Он вычисляет положение студенческого узла, а затем печатает данные студента (ов) вместе с серийным номером.
XPath — Overview
Before learning XPath, we should first understand XSL which stands for Extensible Stylesheet Language. It is similar to XML as CSS is to HTML.
Need for XSL
In case of HTML documents, tags are predefined such as table, div, span, etc. The browser knows how to add style to them and display them using CSS styles. But in case of XML documents, tags are not predefined. In order to understand and style an XML document, World Wide Web Consortium (W3C) developed XSL which can act as an XML-based Stylesheet Language. An XSL document specifies how a browser should render an XML document.
Following are the main parts of XSL −
-
XSLT − used to transform XML documents into various other types of document.
-
XPath − used to navigate XML documents.
-
XSL-FO − used to format XML documents.
What is XPath?
XPath is an official recommendation of the World Wide Web Consortium (W3C). It defines a language to find information in an XML file. It is used to traverse elements and attributes of an XML document. XPath provides various types of expressions which can be used to enquire relevant information from the XML document.
-
Structure Definitions − XPath defines the parts of an XML document like element, attribute, text, namespace, processing-instruction, comment, and document nodes
-
Path Expressions − XPath provides powerful path expressions select nodes or list of nodes in XML documents.
-
Standard Functions − XPath provides a rich library of standard functions for manipulation of string values, numeric values, date and time comparison, node and QName manipulation, sequence manipulation, Boolean values etc.
-
Major part of XSLT − XPath is one of the major elements in XSLT standard and is must have knowledge in order to work with XSLT documents.
-
W3C recommendation − XPath is an official recommendation of World Wide Web Consortium (W3C).
One should keep the following points in mind, while working with XPath −
- XPath is core component of XSLT standard.
- XSLT cannot work without XPath.
- XPath is basis of XQuery and XPointer.
XPath — Expression
An XPath expression generally defines a pattern in order to select a set of nodes. These patterns are used by XSLT to perform transformations or by XPointer for addressing purpose.
XPath specification specifies seven types of nodes which can be the output of execution of the XPath expression.
- Root
- Element
- Text
- Attribute
- Comment
- Processing Instruction
- Namespace
XPath uses a path expression to select node or a list of nodes from an XML document.
Following is the list of useful paths and expression to select any node/ list of nodes from an XML document.
| S.No. | Expression & Description |
|---|---|
| 1 |
node-name Select all nodes with the given name «nodename» |
| 2 |
/ Selection starts from the root node |
| 3 |
// Selection starts from the current node that match the selection |
| 4 |
. Selects the current node |
| 5 |
.. Selects the parent of the current node |
| 6 |
@ Selects attributes |
| 7 |
student Example − Selects all nodes with the name «student» |
| 8 |
class/student Example − Selects all student elements that are children of class |
| 9 |
//student Selects all student elements no matter where they are in the document |
Example
In this example, we’ve created a sample XML document, students.xml and its stylesheet document students.xsl which uses the XPath expressions under select attribute of various XSL tags to get the values of roll no, firstname, lastname, nickname and marks of each student node.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Students</h2>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<xsl:for-each select = "class/student">
<tr>
<td> <xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Verify the output
XPath — Nodes
In this chapter, we’ll see the XPath expression in details covering common types of Nodes, XPath defines and handles.
| S.No. | Node Type & Description |
|---|---|
| 1 | Root
Root element node of an XML Document. |
| 2 | Element
Element node. |
| 3 | Text
Text of an element node. |
| 4 | Attribute
Attribute of an element node. |
| 5 | Comment
Comment |
XPath — Absolute Path
Location path specifies the location of node in XML document. This path can be absolute or relative. If location path starts with root node or with ‘/’ then it is an absolute path. Following are few of the example locating the elements using absolute path.
/class/student − select student nodes within class root node.
<xsl:for-each select = "/class/student">
/class/student/firstname − select firstname of a student node within class root node.
<p><xsl:value-of select = "/class/student/firstname"/></p>
Example
In this example, we’ve created a sample XML document students.xml and its stylesheet document students.xsl which uses the XPath expressions.
Following is the sample XML used.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/" >
<html>
<body>
<h3>Details of each Students. </h3>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<tr>
<td><xsl:value-of select = "/class/student[1]/@rollno"/></td>
<td><xsl:value-of select = "/class/student[1]/firstname"/></td>
<td><xsl:value-of select = "/class/student[1]/lastname"/></td>
<td><xsl:value-of select = "/class/student[1]/nickname"/></td>
<td><xsl:value-of select = "/class/student[1]/marks"/></td>
</tr>
<tr>
<td>
<xsl:value-of select = "/class/student/@rollno"/>
</td>
<td><xsl:value-of select = "/class/student[2]/firstname"/></td>
<td><xsl:value-of select = "/class/student[2]/lastname"/></td>
<td><xsl:value-of select = "/class/student[2]/nickname"/></td>
<td><xsl:value-of select = "/class/student[2]/marks"/></td>
</tr>
<tr>
<td>
<xsl:value-of select = "/class/student[3]/@rollno"/>
</td>
<td><xsl:value-of select = "/class/student[3]/firstname"/></td>
<td><xsl:value-of select = "/class/student[3]/lastname"/></td>
<td><xsl:value-of select = "/class/student[3]/nickname"/></td>
<td><xsl:value-of select = "/class/student[3]/marks"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Verify the output
XPath — Relative Path
Location path specifies the location of node in XML document. This path can be absolute or relative. If location path starts with the node that we’ve selected then it is a relative path.
Following are few examples locating the elements using relative path.
firstname − select firstname related to student nodes.
<p><xsl:value-of select = "firstname"/></p>
Example
In this example, we’ve created a sample XML document students.xml and its stylesheet document students.xsl which uses the XPath expressions.
Following is the sample XML used.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/" >
<html>
<body>
<h3>Details of each Students. </h3>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<xsl:for-each select = "/class/student">
<tr>
<td><xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Verify the output
XPath — Axes
As location path defines the location of a node using absolute or relative path, axes are used to identify elements by their relationship like parent, child, sibling, etc. Axes are named so because they refer to axis on which elements are lying relative to an element.
Following is the list of various Axis values.
| S.No. | Axis & Description |
|---|---|
| 1 |
ancestor Represents the ancestors of the current node which include the parents up to the root node. |
| 2 |
ancestor-or-self Represents the current node and it’s ancestors. |
| 3 |
attribute Represents the attributes of the current node. |
| 4 |
child Represents the children of the current node. |
| 5 |
descendant Represents the descendants of the current node. Descendants include the node’s children upto the leaf node(no more children). |
| 6 |
descendant-or-self Represents the current node and it’s descendants. |
| 7 |
following Represents all nodes that come after the current node. |
| 8 |
following-sibling Represents the following siblings of the context node. Siblings are at the same level as the current node and share it’s parent. |
| 9 |
namespace Represents the namespace of the current node. |
| 10 |
parent Represents the parent of the current node. |
| 11 |
preceding Represents all nodes that come before the current node (i.e. before it’s opening tag). |
| 12 |
self Represents the current node. |
Following are a few examples on the uses of axes.
firstname − select firstname related to student nodes.
<p><xsl:value-of select = "firstname"/></p> <xsl:value-of select = "/class/student/preceding-sibling::comment()"/>
Example
In this example, we’ve created a sample XML document students.xml and its stylesheet document students.xsl which uses the XPath expressions.
Following is the sample XML used.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<!-- Comment: This is a list of student -->
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/" >
<html>
<body>
<xsl:value-of select = "/class/student/preceding-sibling::comment()"/>
<br/>
<xsl:text>First Student: </xsl:text>
<xsl:value-of select = "/class/student/child::firstname" />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Verify the output
XPath — Operators
In this chapter, we’ll see XPath operators and functions in details covering commonly used XPath defines and handles. XPath defines Operators and functions on Nodes, String, Number and Boolean types.
Following is the list we are going to discuss about.
| S.No. | Operators/Functions & Description |
|---|---|
| 1 | Comparision Operators
Comparision operators to compare values. |
| 2 | Boolean Operators
Boolean operators to check ‘and’, ‘or’ & ‘not’ functionalities. |
| 3 | Number Functions/Operators
Operators/Functions on numbers. |
| 4 | String Functions
Various string functions. |
| 5 | Node Functions/Operators
Various functions and operators acting on nodes. |
XPath — Wildcard
XPath defines the following wildcards on nodes to be used with the XPath expressions.
| S.No. | WildCard & Description |
|---|---|
| 1 |
* used to match any node. |
| 2 |
. used to match the current node in context. |
| 3 |
@* used to match any attribute |
| 4 |
node() used to match node of any type |
Example
This example creates a table of <student> element with their details, by iterating over each student.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Students</h2>
<xsl:apply-templates select = "class/*" />
</body>
</html>
</xsl:template>
<xsl:template match = "class/*">
<xsl:apply-templates select = "@rollno" />
<xsl:apply-templates select = "firstname" />
<xsl:apply-templates select = "lastname" />
<xsl:apply-templates select = "nickname" />
<xsl:apply-templates select = "marks" />
<br />
</xsl:template>
<xsl:template match = "@rollno">
<span style = "font-size = 22px;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "firstname">
First Name:<span style = "color:blue;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "lastname">
Last Name:<span style = "color:green;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "nickname">
Nick Name:<span style = "color:red;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
<xsl:template match = "marks">
Marks:<span style = "color:gray;">
<xsl:value-of select = "." />
</span>
<br />
</xsl:template>
</xsl:stylesheet>
Verify the output
XPath — Predicate
Predicate refers to the XPath expression written in square brackets. It refers to restrict the selected nodes in a node set for some condition. For example,
| S.No. | Predicate & Description |
|---|---|
| 1 |
/class/student[1] Select first student element which is child of the class element. |
| 2 |
/class/student[last()] Select last student element which is child of the class element. |
| 3 |
/class/student[@rolllno = 493] Select student element with rollno 493. |
| 4 |
/class/student[marks>85] Select student element with marks > 85. |
Example
This example creates a table of <student> element with their details, by iterating over each student. It calculates the position of the student node and then prints the student(s) details along with serial no.
students.xml
<?xml version = "1.0"?>
<?xml-stylesheet type = "text/xsl" href = "students.xsl"?>
<class>
<student rollno = "393">
<firstname>Dinkar</firstname>
<lastname>Kad</lastname>
<nickname>Dinkar</nickname>
<marks>85</marks>
</student>
<student rollno = "493">
<firstname>Vaneet</firstname>
<lastname>Gupta</lastname>
<nickname>Vinni</nickname>
<marks>95</marks>
</student>
<student rollno = "593">
<firstname>Jasvir</firstname>
<lastname>Singh</lastname>
<nickname>Jazz</nickname>
<marks>90</marks>
</student>
</class>
students.xsl
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:template match = "/">
<html>
<body>
<h2>Students</h2>
<table border = "1">
<tr bgcolor = "#9acd32">
<th>Roll No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Nick Name</th>
<th>Marks</th>
</tr>
<xsl:for-each select = "/class/student[1]">
<tr>
<td><xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
<xsl:for-each select = "/class/student[last()]">
<tr>
<td><xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
<xsl:for-each select = "/class/student[@rollno = 493]">
<tr>
<td><xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
<xsl:for-each select = "/class/student[marks > 85]">
<tr>
<td><xsl:value-of select = "@rollno"/></td>
<td><xsl:value-of select = "firstname"/></td>
<td><xsl:value-of select = "lastname"/></td>
<td><xsl:value-of select = "nickname"/></td>
<td><xsl:value-of select = "marks"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Verify the output
Язык разметки XML с самого первого стандарта окружает пользователей компьютеров. Таблицы в Excel, выгрузки из интернет-магазинов, RSS-ленты с новостями — все это основано на XML. Хоть визуальное отображение отличается на устройствах и в программах, но в основе всегда лежит единый формат.
Внутри XML-файла может находиться огромное количество информации, поэтому и встает вопрос о перемещении и выборке внутри документа. Как это сделать быстро? Какие средства применять, чтобы в интернет-магазине найти нужный товар из десятков тысяч других? Для навигации и поиска внутри XML используется язык запросов XPath.
В этой статье разберем:
- для кого может быть полезен XPath
- базовые конструкции языка для поиска информации в XML
- чем XPath отличается от CSS-селекторов при поиске в HTML
- Синтаксис XPath
- Отличия от CSS-селекторов
- Кому нужен Xpath
- Заключение
Синтаксис XPath
Для начала создадим базовый пример XML, с которым и будем работать весь урок. Например, список курсов по верстке на Хекслете в XML будет выглядеть так:
<?xml version="1.0" encoding="UTF-8"?>
<courses>
<title>Курсы HTML и CSS (верстка)</title>
<description>На курсах по верстке вы познакомитесь с основами HTML и CSS, научитесь верстать адаптивные страницы, работать с препроцессорами. Освоите современные технологии и инструменты, включая Flex, Sass, Bootstrap.</description>
<course>
<name>Основы современной верстки</name>
<tags>HTML5, CSS, DevTools, верстка</tags>
<duration value="9">9 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/layout-designer-basics</url>
<url lang="en">https://hexlet.io/courses/layout-designer-basics</url>
</course>
<course>
<name>Основы верстки контента</name>
<tags>CSS3, HTML5, Селекторы, Доступность, CSS Columns, CSS Units, Верстка</tags>
<duration value="18">18 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/css-content</url>
<url lang="en">https://hexlet.io/courses/css-content</url>
</course>
<course>
<name>Bootstrap 5: Основы верстки</name>
<tags>Bootstrap 5, Адаптивность, HTML, CSS3</tags>
<duration value="10">10 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/bootstrap_basic</url>
<url lang="en">https://hexlet.io/courses/bootstrap_basic</url>
</course>
</courses>
Это учебный пример, но для отработки навыков XPath подойдет и любой другой XML. Принципы XPath сохранятся при любой структуре файла, потому что по стандарту XML можно использовать элементы с произвольными тегами.
Для тестирования результата подойдут такие онлайн-сервисы, как:
- Code Beautify
- XPather
Абсолютные пути
Самый простой запрос состоит из обращения к корневому элементу. Для этого достаточно выполнить запрос /courses. Нам вернется XML в почти таком же виде, что и в примере выше. Обратите внимание на строку <?xml version="1.0" encoding="UTF-8"?>. Она отличается, потому что элемент не внутри <courses>:
<courses>
<title>Курсы HTML и CSS (верстка)</title>
<description>На курсах по верстке вы познакомитесь с основами HTML и CSS, научитесь верстать адаптивные страницы, работать с препроцессорами. Освоите современные технологии и инструменты, включая Flex, Sass, Bootstrap.</description>
<course>
<name>Основы современной верстки</name>
<tags>HTML5, CSS, DevTools, верстка</tags>
<duration value="9">9 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/layout-designer-basics</url>
<url lang="en">https://hexlet.io/courses/layout-designer-basics</url>
</course>
<course>
<name>Основы верстки контента</name>
<tags>CSS3, HTML5, Селекторы, Доступность, CSS Columns, CSS Units, Верстка</tags>
<duration value="18">18 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/css-content</url>
<url lang="en">https://hexlet.io/courses/css-content</url>
</course>
<course>
<name>Bootstrap 5: Основы верстки</name>
<tags>Bootstrap 5, Адаптивность, HTML, CSS3</tags>
<duration value="10">10 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/bootstrap_basic</url>
<url lang="en">https://hexlet.io/courses/bootstrap_basic</url>
</course>
</courses>
В качестве результата XPath возвращает узлы XML-документа.
Продолжим цепочку и обратимся к описанию из элемента <description>. Для этого добавим в запрос путь к description: /courses/description. Результатом выполнения станет:
<description>На курсах по верстке вы познакомитесь с основами HTML и CSS, научитесь верстать адаптивные страницы, работать с препроцессорами. Освоите современные технологии и инструменты, включая Flex, Sass, Bootstrap.</description>
Путь, который строится от корневого элемента, называется абсолютным. Используем схему из прошлого запроса и обратимся к любому элементу внутри XML.
Попробуем обратиться к имени курса. В этом случае вернется поле <name> из всех курсов. Запрос /courses/course/name вернет:
<name>Основы современной верстки</name>
<name>Основы верстки контента</name>
<name>Bootstrap 5: Основы верстки</name>
Вот список некоторых базовых запросов и их результат:
| Запрос | Результат |
|---|---|
/courses/course |
Все данные из всех элементов <course></course> |
/courses/course/name |
<name>Основы современной верстки</name><name>Основы верстки контента</name><name>Bootstrap 5: Основы верстки</name> |
/courses/course/duration |
<duration value="9">9 часов</duration><duration value="18">18 часов</duration><duration value="10">10 часов</duration> |
Относительные пути
Прошлые запросы строились с помощью абсолютных путей — то есть мы указывали полный путь до информации. Бывают ситуации, когда полный путь не подходит: например, мы хотим обраться к какому-то уникальному полю или не знаем полный путь. В этом случае можно использовать относительный путь — он произведет поиск по всему XML и вернет узлы, подходящие под запрос.
Чтобы записать относительный путь, нужно использовать конструкцию //. После нее можно написать любое поле и получить результат. Например, //name вернет поля <name> из всего XML:
<name>Основы современной верстки</name>
<name>Основы верстки контента</name>
<name>Bootstrap 5: Основы верстки</name>
Проблема такого подхода — уникальность полей. В документах одни и те же имена полей могут обозначать разные данные в зависимости от расположения. Поэтому используйте относительные пути только там, где уверены в возвращаемых данных. Например, в нашем примере название курса может быть заключено в <title>:
<courses>
<title>Курсы HTML и CSS (верстка)</title>
<!-- ... -->
<course>
<title>Основы современной верстки</title>
<!-- ... -->
</course>
<course>
<title>Основы верстки контента</title>
<!-- ... -->
</course>
<course>
<title>Bootstrap 5: Основы верстки</title>
<!-- ... -->
</course>
</courses>
Запрос //title вернет не только имена курсов, но и узел, который находится в <courses>:
<title>Курсы HTML и CSS (верстка)</title>
<title>Основы современной верстки</title>
<title>Основы верстки контента</title>
<title>Bootstrap 5: Основы верстки</title>
Чтобы сэкономить пару секунд, разработчики опускают корневой элемент и пользуются относительными путями. Например, вместо /courses/course/name они пишут //course/name. Для практики попробуйте прошлые примеры перевести на относительные пути с помощью такого механизма.
Несколько примеров запросов с идентичными ответами, как и в прошлой таблице:
| Запрос | Результат |
|---|---|
//course |
Все данные из всех элементов <course></course> |
//name |
<name>Основы современной верстки</name><name>Основы верстки контента</name><name>Bootstrap 5: Основы верстки</name> |
//course/duration |
<duration value="9">9 часов</duration><duration value="18">18 часов</duration><duration value="10">10 часов</duration> |
Предикаты
В примерах запросов к именам возвращались имена всех найденных курсов. В некоторых ситуациях это может быть избыточно. Что делать, если хочется получить данные только по первому курсу в <courses>? На помощь приходят предикаты — конструкции, с помощью которых можно отфильтровать элементы по заданным условиям.
Выберем ключевые слова первого курса по верстке. Для этого достаточно использовать запрос //course[1]/tags:
<tags>HTML5, CSS, DevTools, верстка</tags>
Обратите внимание на[1]. Это предикат с таким условием: «Взять элемент по индексу 1». Попробуйте сделать запрос ко второму или третьему элементу. Достаточно поменять всего одну цифру!
В XPath индексы элементов начинаются с единицы, а не с нуля, как в принятых стандартах программирования. Если вы уже программируете, это может немного запутать.
Предикаты помогают делать точные выборки. Например, получить ссылки на русскоязычные страницы курсов. Для этого нужно получить элементы <url>, у которых атрибут lang равен ru. Делается это указанием атрибута и значения. Чтобы XPath отличил атрибут от элемента перед атрибутом указывается символ @.
Теперь запрос будет выглядеть так: //course/url[@lang="ru"]
<url lang="ru">https://ru.hexlet.io/courses/layout-designer-basics</url>
<url lang="ru">https://ru.hexlet.io/courses/css-content</url>
<url lang="ru">https://ru.hexlet.io/courses/bootstrap_basic</url>
Иногда полезно выбрать элементы, которые имеют хоть какой-то атрибут. Для этого можно использовать конструкцию //*[@*]:
<duration value="9">9 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/layout-designer-basics</url>
<url lang="en">https://hexlet.io/courses/layout-designer-basics</url>
<duration value="18">18 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/css-content</url>
<url lang="en">https://hexlet.io/courses/css-content</url>
<duration value="10">10 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/bootstrap_basic</url>
<url lang="en">https://hexlet.io/courses/bootstrap_basic</url>
По примеру выше видно, знак * обозначает «все/любой».
Когда выбраны элементы по атрибутам, можно произвести дополнительную фильтрацию по этим значениям. Например, найдем элементы <duration> со значением атрибута value больше 9. Внутри предикатов используются операторы сравнения, знакомые по языкам программирования:
>— больше<— меньше>=— больше или равно<=— меньше или равно=— равно!=— не равно
Запрос будет выглядеть так: //course/duration[@value > 9]:
<duration value="18">18 часов</duration>
<duration value="10">10 часов</duration>
Мы разобрались, как выбирать одно поле — это интересная, но редкая задача. Чаще разработчики обрабатывают данные по всему файлу или нескольким полям. Попробуем одновременно использовать предикат и обратиться к другим полям. Обратите внимание на два момента:
- Предикат необязательно должен идти в конце запроса
- Внутри предиката могут находиться новые пути, которые нужно проверить
Мы уже знаем, как с помощью предиката отфильтровать данные по полю <duration>. Эту задачу мы выполняли с помощью конструкции duration[@value > 9]. А теперь попробуем сделать эту конструкцию предикатом для <course>. Так мы получим данные о курсах с длительностью больше 9 часов: //course[duration[@value > 9]]:
<course>
<title>Основы верстки контента</title>
<tags>CSS3, HTML5, Селекторы, Доступность, CSS Columns, CSS Units, Верстка</tags>
<duration value="18">18 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/css-content</url>
<url lang="en">https://hexlet.io/courses/css-content</url>
</course>
<course>
<title>Bootstrap 5: Основы верстки</title>
<tags>Bootstrap 5, Адаптивность, HTML, CSS3</tags>
<duration value="10">10 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/bootstrap_basic</url>
<url lang="en">https://hexlet.io/courses/bootstrap_basic</url>
</course>
Можно продолжить этот запрос и получить только имена курсов. Тогда предикат будет в середине запроса, а не в его конце: `//course[duration[@value > 9]]/name
<name>Основы верстки контента</name>
<name>Bootstrap 5: Основы верстки</name>
Функции
В прошлых примерах запросы затрагивали теги и атрибуты. Сами данные мы не затрагивали, хотя это огромный пласт информации, по которой можно делать выборки. Для решения этой задачи используются встроенные в XPath функции. Они являются частью предикатов — например, @. Попробуем найти курс с названием «Основы верстки контента».
Для поиска по тексту внутри элемента используется функция text(). Ее задача — получить текстовое значение элемента и сравнить его с условием по необходимости. Вот как будет выглядеть запрос для поиска курса с нужным именем: //course[name[text()="Основы верстки контента"]]
<course>
<name>Основы верстки контента</name>
<tags>CSS3, HTML5, Селекторы, Доступность, CSS Columns, CSS Units, Верстка</tags>
<duration value="18">18 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/css:content</url>
<url lang="en">https://hexlet.io/courses/css:content</url>
</course>
Но что, если нам известно только часть названия? Для этого существует функция contains(), которая принимает два аргумента:
- Строка, где будет производиться поиск
- Подстрока, которая будет искаться
Для примера найдем курс, у которого в ключевых словах есть слово «Bootstrap». Функция примет текстовое значение элемента tags и найдет там слово «Bootstrap»: //course[tags[contains(text(), "Bootstrap")]]
<course>
<name>Bootstrap 5: Основы верстки</name>
<tags>Bootstrap 5, Адаптивность, HTML, CSS3</tags>
<duration value="10">10 часов</duration>
<url lang="ru">https://ru.hexlet.io/courses/bootstrap_basic</url>
<url lang="en">https://hexlet.io/courses/bootstrap_basic</url>
</course>
В стандарте XPath существует еще несколько функций, но цель статьи — показать принципы работы тех или иных механизмов, а не дать исчерпывающую документацию по всему языку.
Отличия от CSS-селекторов
Если вы писали на JavaScript, то знаете, что элементы можно искать с помощью CSS-селекторов, используя методы querySelector() или querySelectorAll(). Почему же разработчики иногда ищут элементы внутри HTML именно с помощью XPath?
Дело в концепции поиска элементов. Используя CSS, можно идти только в глубину без возможности обратиться к родительским элементам. В отличие от CSS, XPath позволяет в любой момент обращаться и к дочерним, и к родительским элементам.
Если вы хотите подробнее изучить поиск по HTML с помощью XPath, рекомендуем обратиться к статье Introduction to using XPath in JavaScript.
С помощью CSS нельзя найти все элементы div, внутри которых есть ссылки — можно найти сами ссылки, но не их родителей. XPath позволяет это сделать простым сочетанием div[a]. Постепенно ситуация меняется: в CSS появился селектор :has(), но он поддерживается еще не всеми новыми версиями браузеров. Со временем это изменится, но пока реальность именно такая.
Другой пример — поиск элементов по тексту внутри них. С этой задачей CSS никогда не справится, так как такой цели у него нет. XPath, как мы изучили, умеет это делать с помощью функции text().
Кому нужен Xpath
Если коротко, Xpath нужен всем, кто работает с XML.
Чтобы разобраться подробнее, изучим несколько примеров:
SEO-специалисты. Специалисты по продвижению часто обрабатывают большие массивы данных и вытаскивают информацию со страниц сайта.
Например, для них критичны мета-теги — дополнительная информация, в которой содержатся иконки сайтов, название страницы, описание и так далее. Эту информацию SEO-специалист может автоматически парсить с помощью запросов в XPath.
Тестировщики. При работе с Front-end тестировщики часто проверяют тот или иной вывод информации на странице — для этого они выбирают отдельные элементы с нужной страницы. Это можно делать через XPath и DevTools, встроенный в браузеры на основе Chromium.
Разработчики. Они часто используют парсеры — это скрипты, которые ищут нужную информацию на страницах одного или нескольких сайтов. Например, мы хотим сравнить стоимость одного и того же товара в разных магазинах. Для такой задачи можно написать скрипт, который пройдется по всем нужным сайтам, сравнит цены и вернет данные. В этом случае для поиска информацию на странице можно использовать XPath.
Это лишь часть сценариев, в которых пригождается язык XPath — на самом деле, их десятки.
Заключение
В этой статье мы рассмотрели, где встречается XML и кому он может пригодиться. Мы научились составлять базовые запросы и изучили часто используемые конструкции XPath:
- Абсолютные и относительные пути
- Предикаты
- Поиск по атрибутам
- Операторы сравнения
- Функции
Также теперь вы знаете, что поиск по HTML с помощью XPath может быть эффективнее поиска с помощью CSS-селекторов.
В этой статье мы постарались дать знания, которые помогут справиться с большинством задач. Но это далеко не все возможности XPath — это более глубокий язык, чем представлено в статье. Как и с другими технологиями, тут важно набить руку. Чем больше вы практикуетесь, тем более точные и полезные запросы пишете.
Время на прочтение
4 мин
Количество просмотров 493K
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 запрос к выбранному элементу.
Если вы выделили заголовок первого события, то запрос будет таким:
.//*[@id='w3c_home_upcoming_events']/ul/li[1]/div[2]/p[1]/a
После удаления лишних индексов запрос станет соответствовать всем элементам типа «заголовок».
.//*[@id='w3c_home_upcoming_events']/ul/li/div/p/a
Firepath подсвечивает элементы, которые соответствуют запросу. Вы можете в реальном времени увидеть, какие узлы документа соответствуют запросу.
Идем дальше. Создаем запросы для поиска мест проведения конференций и их спонсоров либо с помощью селектора, либо модифицировав первый запрос.
Запрос для получения информации о местах проведения конференций:
.//*[@id='w3c_home_upcoming_events']/ul/li/div/p[2]
Так мы получим список спонсоров:
.//*[@id='w3c_home_upcoming_events']/ul/li/div/p[3]
Синтаксис 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[2]
Где p[2] – второй элемент в наборе для каждого узла списка /ul/li/div.
Аналогично список спонсоров мы можем получить запросом:
.//*[@id='w3c_home_upcoming_events']/ul/li/div/p[3]
Некоторые функции хpath
В хpath существует множество функций для работы с элементами внутри коллекции. Я приведу только некоторые из них.
last():
Возвращает последний элемент коллекции.
Запрос ul/li/div/p[last()] — возвратит последние параграфы для каждого узла списка «ul».
Функция first() не предусмотрена. Для доступа к первому элементу используйте индекс «1».
text():
Возвращает тестовое содержание элемента.
.//a[text() = 'Archive'] – получаем все ссылки с текстом «Archive».
position() и mod:
position() — возвращает позицию элемента в множестве.
mod — остаток от деления.
Комбинацией данных функций можем получить:
— не четные элементы ul/li[position() mod 2 = 1]
— четные элементы: ul/li[position() mod 2 = 0]
Операции сравнения
- < — логическое «меньше»
- > — логическое «больше»
- <= — логическое «меньше либо равно»
- >= — логическое «больше либо равно»
ul/li[position() > 2] , ul/li[position() <= 2] — элементы списка начиная с 3го номера и наоборот.
Полный список функций
Самостоятельно
Попробуйте получить:
— четные URL ссылки из левого меню «Standards»;
— заголовки всех новостей, кроме первой с главной страницы w3c.org.
Xpath в PHP5
$dom = new DomDocument();
$dom->loadHTML( $HTMLCode );
$xpath = new DomXPath( $dom );
$_res = $xpath->query(".//*[@id='w3c_home_upcoming_events']/ul/li/div/p/a");
foreach( $_res => $obj ) {
echo 'URL: '.$obj->getAttribute('href');
echo $obj->nodeValue;
}
В заключение
На простом примере мы увидели возможности xpath для доступа к узлам веб-страниц.
Xpath является отраслевым стандартом для доступа к элементам xml и xhtml, xslt преобразований.
Вы можете применять его для парсинга любой html-страницы. В случае если исходный html-код содержит значительные ошибки в разметке пропустите его через tidy. Ошибки будут исправлены.
Старайтесь отказаться от регулярных выражений при парсинге веб-страниц в пользу xpath.
Это сделает ваш код проще, понятнее. Вы допустите меньше ошибок. Сократиться время отладки.
Ресурсы
Firepath дополнение Mozzilla Firefox
Краткая аннотация языка в википедии
Xороший справочник по xpath. Не обращайте внимание на то, что он для NET Framework. Xpath во всех средах работает одинаково, за исключением пары специфичных функций
Cпецификация xpath 1.0
Cпецификация xpath 1.0 на русском
XQuery 1.0 and XPath 2.0
Tidy
PHP5 tidy::repairFile
XPath – основной элемент в стандарте XSLT.
XPath может использоваться для навигации по элементам и атрибутам XML документа.
Данный учебник рассказывает о базовых понятиях и синтаксисе языка XPath.
- XPath расшифровывается как XML Path Language
- XPath использует синтаксис путей для идентификации и навигации по узлам XML документа
- XPath содержит более 200 встроенных функций
- XPath является основным элементом в стандарте XSLT
Intro
With the craze of microservices having a continuous integration pipeline with your favorite
A big part of having a CI pipeline in place is automated tests, which includes regression tests for your UI component.
TLDR
Add unique identifiers to the elements you wish to interact with inside of your tests either using the html attribute “id” or your own attribute/combination of attributes. Then have very simple locators of
//*[@id=the_unique_identifier]
or
//*[@attribute1=part_of_unique_identifier and @attribute2=other_part_of_unique_identifier]
So what exactly is XPath? Well as defined the XPath website itself, “XPath is a language for addressing parts of an XML document, designed to be used by both XSLT and XPointer.”
To try out the following selectors or to test out your own try this test bed
Or if you want to try out/test xpath selectors directly on a website open up your dev tools (f12) in chrome and test them out.
Another useful tip is a pages DOM structure will often change upon hovering/moving the mouse around, to get around this you can temporarily disable the javascript on a page by hitting F1 and disabling javascript.
Examples
Intro
Many XPath expressions resemble that of traversing your favorite Unix filesystem ie cd / navigates you to the root direction / as a XPath expression returns the root element.
Lets start off with this simple html block:
<body>
<div>
<span>
<p>
<strong>
XPath is awesome!
</strong>
</p>
</span>
</div>
</body>
Here the expression / would return the entire html block while /body/div/span/p would return <p><strong>XPath is awesome!</strong></p>.
Similarly /body/div/span/p/strong would return <strong>XPath is awesome!</strong>.
Writing the entire path to an element can get tedious for that we can use // vs /. The difference between the two is / is for absolute paths while // is for relative paths. For example /body/strong will only match with elements which are strong and the direct child of a body tag, in this case it will match with nothing. However /body//strong will return <strong>XPath is awesome!</strong>.
You may have noticed all the expressions so far have started off with /body as you can probably figure out this means we are looking for a body top level element, and could use //body.
Attributes
This time will use the following html block:
<body>
<div id='Article'>
<div id='Title' class='Bold Highlighted Box'>
Lorem Ipsum
</div>
<div id='Content'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et interdum ipsum.
</div>
<div id='Footer'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et interdum ipsum.
</div>
</div>
</body>
Lets get the div with an id of Title for that the following expression will work //div[@id='Title'] pretty simple right? Also goes to show you how useful giving elements a unique tag will be for testing.
XPath selectors work for all types of attributes //div[@class='Bold Highlighted Box'] will also return the title div.
Now what if we dont know the full value of the attribute, here we can use starts-with and ends-with. For example lets say we want to select all elements that have a class ending with Box we could use the following selector //div[ends-with(@class, 'Box')].
Unfortunately XPath does not have a great way of checking if part of a space separated list equals to something else so the following hack could be used //div[contains(concat(' ', normalize-space(@class), ' '), ' expected-class ')]. This is very useful for doing a class check.
Operators
So far all our queries have been using the standard = operator but as in most programming languages XPath has access to many other operators such as !=, >, >=, <=, and, or, not.
For example
<body>
<div role='row'>
<div role='product' class='unselected' price='25'>
Toothbrush
</div>
<div role='product' class='unselected' price='25'>
Haircomb
</div>
<div role='product' class='unselected' price='10'>
Flour
</div>
<div role='promotion' class='unselected' price='25'>
Rice
</div>
</div>
</body>
Now lets get all the divs that are products, are unselected by the user and cost more than 20$, //div[@role='product' and @class='unselected' and @price > 20]. This will return both the toothbrush div and the haircomb div.
Axes (Parents/children)
So far we have been creating selectors that pick children of an element, ie /body/div/span we are selecting spans that are inside of divs which are insides of bodies. But what about getting ancestors or siblings?
For those cases one can use the various built in axes such as descendant-or-self or following-sibling.
Using the following html as our example
<body>
<div>
<span>
Hello
</span>
</div>
</body>
Now lets get the first div ancestor of the span containing Hello //span[contains(text(),'Hello')]/ancestor-or-self::div.
Cheatsheet
Heres a great cheatsheet with a few more sample querys.
When it comes to parsing web-scraped HTML content, there are multiple techniques to select the data we want.
For simple text parsing, regular expression can be used, but HTML is designed to be a machine-readable text structure. We can take advantage of this fact and use special path languages like CSS selectors and XPath to extract data in a much more efficient and reliable way!
You are probably familiar with CSS selectors from the style sheet documents (.css) however, XPath goes beyond that and implements full document navigation in its own unique syntax.
Parsing HTML with CSS Selectors
For parsing using CSS selectors see the CSS version of this article
In this article, we’ll be taking a deep look at this unique path language and how can it be used to extract needed details from modern, complex HTML documents. We’ll start with a quick introduction and expression cheatsheet and explore concepts using an interactive XPath tester.
Finally, we’ll wrap up by covering XPath implementations in various programming languages and some common idioms and tips when it comes to XPath in web scraping. Let’s dive in!
What is Xpath?
XPath stands for «XML Path Language» which essentially means it’s a query language that described a path from point A to point B for XML/HTML type of documents.
Other path languages you might know of are CSS selectors which usually describe paths for applying styles, or tool-specific languages like jq which describe paths for JSON-type documents.
For HTML parsing, Xpath has some advantages over CSS selectors:
- Xpath can traverse HTML trees in every direction and is location-aware.
- Xpath can transform results before returning them.
- Xpath is easily extendable with additional functionality.
Before we dig into Xpath let’s have a quick overview of HTML itself and how it enables xpath language to find anything with the right instructions.
HTML Overview
HTML (HyperText Markup Language) is designed to be easily machine-readable and parsable. In other words, HTML follows a tree-like structure of nodes and their attributes, which we can easily navigate programmatically.
Let’s start off with a small example page and illustrate its structure:
<head>
<title>
</title>
</head>
<body>
<h1>Introduction</h1>
<div>
<p>some description text: /p>
<a class="link" href="https://example.com">example link</a>
</div>
</body>
In this basic example of a simple web page, we can see that the document already resembles a data tree. Let’s go a bit further and illustrate this:
HTML tree is made of nodes which can contain attributes such as classes, ids and text itself.
Here we can wrap our heads around it a bit more easily: it’s a tree of nodes and each node can also have properties attached to them like keyword attributes (like class and href) and natural attributes such as text.
Now that we’re familiar with HTML let’s familiarize ourselves with Xpath itself!
Xpath Syntax Overview
Xpath selectors are usually referred to as «xpaths» and a single xpath indicates a destination from the root to the desired endpoint. It’s a rather unique path language, so let’s start off with a quick glance over basic syntax.
Average xpath selector in web scraping often looks something like this:
illustration of a usual xpath selector’s structure
In this example, XPath would select href attribute of an <a> node that has a class «button» which is also directly under <div> node:
<div>
<a class=»button» href=»http://scrapfly.io»>ScrapFly</a>
</div>
Xpath selectors are made up of multiple expressions joined together into a single string. Let’s see the most commonly used expressions in this XPath cheat sheet:
| expression | description |
|---|---|
/node |
selects a direct child that matches node name. |
//node |
selects any descendant — child, grandchild, gran-grandchild etc. |
* |
wildcard can be used instead of node name |
@ |
selects an attribute of a node e.g. a/@href will select value of href attribute of an a node |
text() |
selects text value of a node |
[] |
selector constraint — can be used to filter out nodes that do no match some condition |
parent or .. |
select current nodes parent e.g. /div/a/.. will select div element |
self or . |
select current node (this is useful as argument in xpath function, we’ll cover more later) |
following-sibling::node |
selects all following siblings of type, e.g. following-sibling::div will select all div siblings below the current node |
preceding-sibling::node |
selects all preceding siblings of type, e.g. preceding-sibling::div will select all div siblings below the current node |
function() |
calls registered xpath function e.g. /a/text() will return text value of a node |
This XPath cheatsheet might be a lot to take in — so, let’s solidify this knowledge with some real-life examples.
Basic Navigation
When writing xpaths the first thing we should be aware of is that all xpaths have to have a root (aka point A) and final target (aka point B). Knowing this and xpath axis syntax, we can start describing our selector path:
<div>
<p class=»socials»>
Follow us on
<a href=»https://twitter.com/@scrapfly_dev»>Twitter!</a>
</p>
</div>
Here, our simple xpath simply describes a path from the root to the a node.
All we used is / direct child syntax, however with big documents direct xpaths are often unreliable as any changes to the tree structure or order will break our path.
It’s better to design our xpaths around some smart context. For example, here we can see that this <a> node is under <p class="socials"> node — we can infer strong sense that these two will most likely go together:
<div>
<p class=»socials»>
Follow us on
<a href=»https://twitter.com/@scrapfly_dev»>Twitter!</a>
</p>
</div>
With this xpath, we get rid a lot of structure dependency in favor of context. Generally, modern websites have much more stable contexts than structures, and finding the right balance between context and structure is what creates reliable xpaths!
Further, we can combine constrains option ([]) with value testing functions such as contains() to make our xpath even more reliable:
<div>
<p class=»socials»>
Follow us on
<a href=»https://twitter.com/@scrapfly_dev»>Twitter!</a>
</p>
</div>
Using XPath contains() text function, we can filter out any results that don’t contain a piece of text.
Xpath functions are very powerful and not only they can check for truthfulness but also modify content during runtime:
<div>
<p class=»socials»>
Follow us on
<a href=»https://twitter.com/@scrapfly_dev»>Twitter!</a>
or connect with us on
<a href=»https://www.linkedin.com/company/scrapfly/»>Linkedin</a>
</p>
</div>
Here, we’ve added concat() function, which joins all provided arguments into a single value and only then perform our match check.
Navigating Complex Structures
Sometimes tree complexity outgrows context based selectors and we have to implement some complex structure checks. For that, xpath has powerful tree navigation features that allow to select ancestors and siblings of any level:
<div>
<span>For price contact </span>
<a>Sales department </a>
<div>
<span>total: </span>
</div>
<span>166.00$</span>
<span>*taxes apply</span>
</div>
In this example, we find a text containing the phrase «total», navigate up to its parent and get the first following sibling using XPath.
Other times, we need to use position-based predicates and even combine multiple XPaths to reliably parse HTML data:
<div>
<span>items: </span>
<span>(taxes not included)</span>
<span>166.00$</span>
<span>25.00$</span>
<span>*taxes apply</span>
<div>
<span>addons:</span>
<span>0.5$</span>
</div>
</div>
In this example, we used position() function to select only siblings that are in specific range. We also combined to xpaths using the | operator (for or operation or operator can being used) to fully retrieve all pricing info.
As you can see, xpaths can be very powerful and parse almost any html structure if we get creative with path logic!
Extending Functions
Xpath in most clients can be extended with additional functions, and some clients even come with pre-registered non-standard functions.
For example, in Python’s lxml (and it’s based packages like parsel) we can easily register new functions like this:
from lxml import etree
def myfunc(context, *args):
return True
xpath_namespace = etree.FunctionNamespace(None)
xpath_namespace['myfunc'] = myfunc
Other language clients follow a similar process.
Xpath Clients
Almost every programming language contains some sort of xpath client for XML file parsing. Since HTML is just a subset of XML we can safely use xpath in almost every modern language!
Xpath in Python
In Python there are multiple packages that implement xpath functionality, however most of them are based on lxml package which is a pythonic binding of libxml2 and libxslt C language libraries. This means Xpath selectors in Python are blazing fast, as it’s using powerful C components under the hood.
While lxml is a great wrapper, it lacks a lot of modern API usability features used in web scraping. For this, lxml based packages parsel (used by scrapy) and pyquery provide a richer feature set.
Example usage with parsel:
from parsel import Selector
html = """
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1 class="title">Page header by <a href="#">company</a></h1>
<p>This is the first paragraph</p>
<p>This is the second paragraph</p>
</body>
</html>
"""
sel = Selector(html)
sel.xpath("//p").getall()
# [
# "<p>This is the first paragraph</p>",
# "<p>This is the second paragraph</p>",
# ]
Other tool recommendations:
- cssselect — converts css selectors to xpath selectors
- parsel-cli — real time REPL for testing css/xpath selectors
Xpath in PHP
In PHP most popular xpath processor is Symphony’s DomCrawler:
use SymfonyComponentDomCrawlerCrawler;
$html = <<<'HTML'
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1 class="title">Page header by <a href="#">company</a></h1>
<p>This is the first paragraph</p>
<p>This is the second paragraph</p>
</body>
</html>
HTML;
$crawler = new Crawler($html);
$crawler->filterXPath('//p');
Other tool recommendations:
- css-selector — converts css selectors to xpath selectors
Xpath in Javascript
Javascript supports xpath natively, you can read more about it on MDN’s Introduction to Using Xpath in Javascript
Other tool recommendations:
- jQuery — extra syntax sugar and helpers for xpath querying.
- cash — lightweight, modern jQuery alternative.
Xpath in Other Languages
Most other languages have some sort of XPath client as XML parsing is an important data exchange feature. Meaning, we can parse web-scraped content in the language of our choice!
For example, C# supports XPath natively as well, you can read more about it over at the official documentation so does Objecive C and other low-level languages.
While some languages might not have first-party XPath clients it’s very likely there’s a community package. For example, Go language has community packages for xpath in xml, html and even json.
Xpath in Browser Automation
Browser automation tools support XPath without any additional Javascript packages.
To access XPath in Selenium we can use by.XPath selector. For example, for Selenium in Python:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://httpbin.org/html")
element = driver.find_element(By.XPATH, '//p')
To access XPath in Playwright we can use the locator functionality which take either CSS selectors or XPath as the argument. For example in Playwright and Python:
from playwright.sync_api import sync_playwright
with sync_playwright() as pw:
browser = pw.chromium.launch(headless=False)
context = browser.new_context(viewport={"width": 1920, "height": 1080})
page = context.new_page()
page.goto("http://httpbin.org/html")
paragraphs = page.locator("//p") # this can also take CSS selectors
To access XPath in Puppeteer we can use the $ and $$ methods. For example in Puppeteer in Javascript:
const puppeteer = require('puppeteer')
const browser = await puppeteer.launch();
let page = await browser.newPage();
await page.goto('http://httpbin.org/html');
await page.$("//p");
FAQ
To wrap this introduction up let’s take a look at some frequently asked questions regarding HTML parsing using XPath selectors:
Is XPATH faster than CSS selectors?
Many CSS selector libraries convert CSS selectors to XPATH because it’s faster and more powerful. That being said it depends on each individual library and complexity of the selector itself. Some XPATH selectors which use broad selection paths like // can be very expensive computationally.
My xpath selects more data than it should
XPATH broad selector paths like // are global rather than relative. To make them relative we must add the relativity marker . -> .//
How to match nodes by multiple names?
To match nodes by multiple names we can use wildcard selector together with a name check condition: //*[contains("p h1 head", name())] — will select h1, p and head nodes.
How to select select elements between two nodes?
If we know two nodes like text headers we can select text between with clever use of preceding-sibling notation:
//h2[@id="faq"]//following-sibling::p[(preceding-sibling::h2[1])[@id="faq"]] — this xpath selects all paragraph nodes under h2 tag with id faq and not elements under other h2 nodes.
<div>
<span>items: </span>
<span>(taxes not included)</span>
<span>166.00$</span>
<span>25.00$</span>
<span>*taxes apply</span>
<div>
<span>addons:</span>
<span>0.5$</span>
</div>
</div>
Summary
In this article, we’ve introduced ourselves with xpath query language. We’ve discovered that HTML documents are data trees with nodes and attributes which can be machine parsed efficiently.
We glanced over the most commonly used XPath syntax and functions and explored common HTML parsing scenarios and best practices using our interactive XPath tester.
Xpath is a very powerful and flexible path language that is supported in many low-level and high-level languages: Python, PHP, Javascript etc. — so, whatever stack you’re using for web-scraping, XPath can be your to-go tool for HTML parsing!
For more XPath help we recommend visiting Stackoverflow’s #xpath tag and see our data parsing tag for more articles on data parsing.

















