Таким образом, предикаты определяют свойства, которыми должны обладать выбираемые узлы.
Примеры:
□ a[1]— выберет первый в порядке просмотра документа дочерний элемент аконтекстного узла;
□ a[position() mod 2 = 0]— выберет все четные дочерние элементы а;
□ *[. = 'а']— выберет все дочерние элементы, текстовое значение которых равно " а";
□ *[name() = 'a']— выберет все дочерние элементы, имя которых равно " а";
□ *[starts-with(name(), 'a')]— выберет все дочерние элементы, имя которых начинается с " а";
□ *[. = 'а'][1]— выберет первый дочерний элемент, текстовое значение которого равно " а";
□ *[. = 'a'][position() mod 2 = 0]— выберет все дочерние элементы, текстовое значение которых равно " а", затем из них выберет четные элементы.
Пути выборки — это наиболее часто используемые XPath-выражения и для того, чтобы сделать их менее громоздкими, в XPath имеется так называемый сокращенный синтаксис, с которым мы уже встречались в предыдущих главах. Его продукции записываются следующим образом:
[XP10] AbbreviatedAbsoluteLocationPath
:: = '//' RelativeLocationPath
[XP11] AbbreviatedRelativeLocationPath
::= RelativeLocationPath '//' Step
[XP12] AbbreviatedStep
::= '.'
| '..'
[XP13] AbbreviatedAxisSpecifier
::= '@'?
Первое сокращение, '//'— это краткая версия для "/descendant-or-self::node()/". Шаг выборки descendant-or-self::node()возвращает всех потомков контекстного узла (не включая узлов атрибутов и пространств имен). Сокращенный путь вида '//' RelativeLocationPathраскрывается в путь вида
'/descendant-or-self::node()/' RelativeLocation
а путь вида RelativeLocationPath '//' Step— в путь
RelativeLocationPath '/descendant-or-self::node()/' Step
Сокращенный шаг вида '.'возвращает контекстный узел, его полная версия — self::node().
Сокращенный шаг ' ..' возвращает родительский узел контекстного узла. Это сокращение равносильно шагу выборки parent::node().
Заметим, что сокращения "."и ".."являются сокращенными шагами выборки. Это, в частности, означает, что к ним нельзя присовокуплять предикаты и так далее. Выражение ".[ancestor::body]"будет с точки зрения синтаксиса XPath некорректным. Вместо этого можно использовать выражение "self::node()[ancestor::body]", которое будет синтаксически правильным.
Наиболее часто используемой осью навигации является ось child, содержащая все дочерние узлы контекстного узла. Шаги выборки, которые обращаются к дочерним узлам, имеют вид 'child::' NodeTest Predicate*. Самым полезным сокращением является то, что в шагах такого вида дескриптор оси 'child::'может быть опущен, и тогда упрощенные шаги будут иметь вид NodeTest Predicate*.
Дескриптор оси навигации 'attribute::'также может быть сокращен до '@'. Шаг выборки 'attribute::' NodeTest Predicate*может быть переписан с использованием, сокращенного синтаксиса в виде '@'. NodeTest Predicate*.
Примеры:
□ .//*— выберет все элементы-потомки контекстного узла;
□ ..//*— выберет все дочерние элементы родителя контекстного узла;
□ @*— выберет все атрибуты контекстного узла;
□ .//@*— выберет все атрибуты всех потомков контекстного узла;
□ //*— выберет все элементы документа, содержащего контекстный узел;
□ //@*— выберет все атрибуты всех элементов документа, содержащего контекстный узел;
□ html/body— выберет элементы body, принадлежащие дочерним элементам htmlконтекстного узла.
Простые шаги выборки:
□ child::*— выберет все дочерние элементы контекстного узла;
□ child::comment()— выберет все узлы комментариев контекстного узла;
□ child::node()— выберет все дочерние узлы контекстного узла вне зависимости от их типа;
□ child::query— выберет все дочерние элементы контекстного узла, имеющие имя query;
□ child::xsql:*— выберет все дочерние элементы, которые находятся в пространстве имен, определяемом префиксом xsql;
□ child::xsql:query— выберет все дочерние элементы query, которые находятся в пространстве имен, определяемом префиксом xsql;
□ attribute::*— выберет все атрибуты контекстного узла;
□ attribute::href— выберет атрибут hrefконтекстного узла, если он существует;
□ parent::*— выберет родительский узел контекстного узла, если тот является элементом, и пустое множество, если родительский узел имеет другой тип, например является корнем дерева;
Читать дальше