Открыть список
Как стать автором
Обновить

Три редкоиспользуемые оси в XPath

XSLT
Основная мощь языка XPath заключается в осях, позволяющих добраться до любого элемента в исходном документе. Рассмотрим применение таких редкоиспользуемых осей, как ancestor, descendant и self.

ancestor


Задача: получить атрибут id элемента-«прадеда» foo.

Обычно в таких случаях начинают рисовать лестницы:

../../../@id

Такая запись плоха тем, что малопонятна без знания исходного xml. Автор рекомендует в подобных случаях использовать более информативное выражение:

ancestor::foo[1]/@id

Эта запись не только даёт представление об искомом элементе, но и продолжает работать даже в том случае, когда текущий элемент изменил своё положение в дереве.

descendant


Задача: найти первого потомка foo в текущем элементе.

Когда похожий вопрос был задан на сайте StackOverflow.com, два человека тут же ответили .//foo[1] и были поддержаны другими участниками. Автору пришлось вмешаться и предупредить о неправильности данного выражения. Правильный ответ: descendant::foo[1], и вот почему.

.//foo является короткой формой следующего выражения:

self::node()/descendant-or-self::node()/child::foo

Запись .//foo[1] означает все потомки foo, каждый из которых первый foo у своего родителя. Такое выражение вернёт два элемента в следующем документе:

<list>
    <item><foo/></item>
    <item><foo/></item>
</list>

descendant::foo[1] вернёт ровно один элемент.

Это различие описано в документации, но почему-то многие читают её невнимательно. Во избежание ошибок автор рекомендует всегда писать descendant::foo вместо .//foo, поскольку в подавляющем большинстве случаев именно это и имеется в виду.

self


Казалось бы, зачем нужна self, если есть более короткий вариант: . (точка). Однако и у этой оси нашлось своё применение.

Задача: получить следующий элемент, если он называется foo.

Очевидное решение:

following-sibling::*[1][name() = 'foo']

Более элегантное, на взгляд автора, выражение:

following-sibling::*[1]/self::foo

Комментарии и дополнения приветствуются.
Теги:XPathancestordescendantself
Хабы: XSLT
Всего голосов 63: ↑61 и ↓2 +59
Просмотры59.6K

Комментарии 16

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

Похожие публикации

Web-разработчик
от 50 000 до 80 000 ₽AwardWalletПермь
Программист Power BI Senior
от 80 000 до 125 000 ₽ТатнефтьКазаньМожно удаленно
Backend Python/Django
от 2 500 до 3 500 $Borderless360Можно удаленно
Senior Dart / Flutter Developer wanted (remote or office)
от 4 000 до 5 000 $JarSoftНовосибирскМожно удаленно

Лучшие публикации за сутки