XPath-запрос¶
XPath-запрос — это выражение на языке XPath (XML Path Language), предназначенное для навигации по структуре XML-документа и извлечения из него определённых узлов или данных. XPath является одним из основных компонентов стандартов XSLT и XQuery, а также широко используется в веб-скрапинге, парсинге данных и автоматизации тестирования. Язык оперирует древовидной моделью XML-документа, где каждый элемент, атрибут, текстовое содержимое или комментарий представляют собой узел.
¶История и стандартизация
XPath был разработан консорциумом W3C (World Wide Web Consortium) как часть семейства стандартов для работы с XML. Первая версия, XPath 1.0, стала рекомендацией W3C в ноябре 1999 года. Она заложила базовые принципы синтаксиса, включая пути к узлам, предикаты и основные функции. XPath 1.0 остаётся наиболее распространённой версией благодаря поддержке во всех популярных браузерах и библиотеках, таких как lxml (Python), DOM (JavaScript) и Saxon (Java).
Вторая версия, XPath 2.0, была опубликована в январе 2007 года. Она значительно расширила возможности языка: ввела строгую типизацию на основе XML Schema, поддержку последовательностей (вместо наборов узлов), условные конструкции (if-then-else), циклы (for) и богатый набор функций для работы со строками, числами и датами. XPath 2.0 стал основой для XSLT 2.0 и XQuery 1.0.
Третья версия, XPath 3.0, вышла в апреле 2014 года. Она добавила поддержку анонимных функций, встроенных типов данных, таких как массивы и карты, а также улучшила обработку ошибок. XPath 3.1, опубликованная в марте 2017 года, дополнила язык поддержкой JSON-подобных структур (карты и массивы) и функций для работы с ними. На практике, особенно в веб-среде, доминирует XPath 1.0, а более новые версии используются преимущественно в серверных и промышленных решениях (например, в базах данных XML или в трансформациях XSLT).
¶Синтаксис и основные конструкции
XPath-запрос представляет собой выражение, которое вычисляется относительно контекстного узла (обычно корневого узла документа). Основные типы выражений:
¶Пути (Location Paths)
Путь состоит из последовательности шагов, разделённых косой чертой /. Каждый шаг выбирает узлы относительно текущего контекста. Существует два вида путей: абсолютные (начинаются с /) и относительные (начинаются с имени узла или оси).
Примеры:
/bookstore/book— выбирает все элементы<book>, являющиеся прямыми потомками корневого элемента<bookstore>.book/title— выбирает элементы<title>, которые являются прямыми потомками контекстного элемента<book>.//author— выбирает все элементы<author>в документе, независимо от их расположения (сокращение от/descendant::author).
¶Оси (Axes)
Ось определяет направление навигации относительно контекстного узла. Основные оси:
child::— дочерние узлы (используется по умолчанию).descendant::— все потомки.parent::— родительский узел.ancestor::— все предки.following-sibling::— следующие соседние узлы.preceding-sibling::— предыдущие соседние узлы.attribute::— атрибуты узла (сокращение@).self::— сам контекстный узел.
Пример: //book/ancestor::catalog — выбирает все элементы <catalog>, которые являются предками любого элемента <book>.
¶Предикаты (Predicates)
Предикаты — это условия, заключённые в квадратные скобки [], которые фильтруют узлы, выбранные шагом пути. Предикат может содержать числовые индексы, сравнения, вызовы функций или логические выражения.
Примеры:
/bookstore/book[1]— выбирает первый элемент<book>./bookstore/book[price>35]— выбирает книги, у которых значение элемента<price>больше 35.//book[author='John']— выбирает книги, у которых есть автор с текстом «John».//book[position() mod 2 = 0]— выбирает чётные по порядку книги.
¶Функции
XPath включает набор встроенных функций для работы с узлами, строками, числами, логическими значениями и последовательностями. Наиболее часто используемые:
text()— выбирает текстовые узлы.@name— выбирает значение атрибутаname.count(node-set)— возвращает количество узлов.string(node-set)— преобразует узел в строку.contains(string1, string2)— проверяет, содержит ли первая строка вторую.normalize-space(string)— удаляет лишние пробелы.last()— возвращает индекс последнего узла в наборе.not(expression)— логическое отрицание.
Пример: //book[contains(title, 'XML')] — выбирает книги, в заголовке которых встречается подстрока «XML».
¶Типы узлов и модели данных
XPath оперирует следующими типами узлов XML-документа:
- Корневой узел (root node) — представляет весь документ.
- Элемент (element node) — соответствует XML-тегу.
- Текст (text node) — содержимое между тегами.
- Атрибут (attribute node) — значение атрибута элемента.
- Комментарий (comment node) — комментарий в XML.
- Инструкция по обработке (processing instruction node) — например,
<?xml version="1.0"?>. - Пространство имён (namespace node) — объявление пространства имён.
В XPath 1.0 все узлы, выбранные путём, образуют набор узлов (node-set) — неупорядоченное множество без дубликатов. В XPath 2.0 и выше узлы организуются в последовательности (sequences), которые могут содержать дубликаты и сохранять порядок.
¶Применение
¶Веб-скрапинг и парсинг HTML
XPath активно используется в инструментах для извлечения данных из веб-страниц, таких как Scrapy (Python), Selenium и Puppeteer. Поскольку HTML является подмножеством XML, XPath-запросы позволяют гибко выбирать элементы по их структуре, атрибутам и текстовому содержимому. Например, запрос //div[@class='product']//span[@class='price'] извлекает все цены товаров с определённым классом.
¶XSLT-трансформации
В языке XSLT (XSL Transformations) XPath используется для выбора узлов, которые будут обработаны шаблонами, а также для вычисления значений атрибутов и содержимого выходных элементов. Например, атрибут select в элементе <xsl:apply-templates> содержит XPath-выражение, определяющее, какие узлы обрабатывать.
¶Базы данных XML
Некоторые базы данных, такие как BaseX, eXist-db и MarkLogic, поддерживают XPath как язык запросов для поиска данных в XML-коллекциях. XPath 3.1 с поддержкой карт и массивов позволяет также работать с JSON-данными.
¶Автоматизация тестирования
В инструментах тестирования пользовательских интерфейсов (например, Selenium WebDriver) XPath используется для поиска элементов веб-страницы по их расположению в DOM-дереве. Это особенно полезно, когда у элемента нет уникальных идентификаторов или классов.
¶Примеры XPath-запросов
Для иллюстрации рассмотрим фрагмент XML-документа:
``xml <bookstore> <book category="fiction"> <title lang="en">The Great Gatsby</title> <author>F. Scott Fitzgerald</author> <price>10.99</price> </book> <book category="nonfiction"> <title lang="en">A Brief History of Time</title> <author>Stephen Hawking</author> <price>15.50</price> </book> </bookstore> ``
//book[price>12]— выбирает книгу с ценой больше 12 (вторую).//book/@category— выбирает атрибутыcategoryвсех книг.//title[../author='Stephen Hawking']— выбирает заголовок книги, у которой автор — Стивен Хокинг.//book[1]/*[last()]— выбирает последний дочерний элемент первой книги (в данном случае<price>10.99</price>).
¶Критика и ограничения
XPath 1.0, несмотря на свою популярность, имеет ряд недостатков. Отсутствие строгой типизации и ограниченный набор функций затрудняют сложные вычисления. Наборы узлов не поддерживают порядок, что может приводить к неожиданным результатам при использовании предикатов с позициями. Кроме того, синтаксис XPath может быть трудночитаемым для длинных и сложных запросов, особенно при использовании осей и вложенных предикатов.
В веб-скрапинге XPath часто конкурирует с CSS-селекторами, которые проще и быстрее в большинстве браузеров. Однако XPath остаётся незаменимым для задач, требующих навигации по дереву вверх (к родителю или предку) или выбора элементов на основе текстового содержимого.
¶Источники
- W3C Recommendation: XML Path Language (XPath) Version 1.0, 1999.
- W3C Recommendation: XPath 2.0, 2007.
- W3C Recommendation: XPath 3.0, 2014.
- Kay, Michael. XPath 2.0 Programmer's Reference. Wiley, 2004.
- Walmsley, Priscilla. XQuery. O'Reilly Media, 2007.