[XP4] Step ::= AxisSpecifier NodeTest Predicate*
| AbbreviatedStep
[XP5] AxisSpecifier ::= AxisName '::'
| AbbreviatedAxisSpecifier
Продукцию Step можно значительно упростить и записать в следующем виде:
Step ::= '.'
| '..'
| NodeTest Predicate*
| '@' NodeTest Predicate*
| AxisName '::' NodeTest Predicate*
В первых четырех случаях шаг выборки записан при помощи сокращенного синтаксиса, а именно:
□ шаг выборки '.' эквивалентен шагу self::node(), который выбирает контекстный узел;
□ шаг выборки '..' эквивалентен шагу parent::node(), который выбирает родительский узел контекстного узла;
□ шаг выборки вида NodeTest Predicate* эквивалентен шагу выборки вида 'child::' NodeTest Predicate*, который выбирает узлы из множества дочерних узлов контекстного узла;
□ шаг выборки вида '@' NodeTest Predicate* эквивалентен шагу выборки вида 'attribute::' NodeTest Predicate*, который выбирает узлы из множества атрибутов контекстного узла.
Последний случай, AxisName ' ::' NodeTest Predicate* представляет полный синтаксис шага выборки: сначала идет наименование оси и тест узла, разделенные двумя двоеточиями ("::"), затем несколько предикатов.
Оси навигации
Важной особенностью путей выборки является то, что шаги в них могут совершаться не в двух направлениях (вглубь и на верхний уровень), как в случае с файловыми системами, а во многих других. При выполнении шага выборки из некоторого контекстного узла направление движения по логическому дереву документа задается первой частью этого шага, осью навигации. В XPath имеется 13 осей навигации, а именно:
□ self — эта ось навигации содержит только сам контекстный узел;
□ child — содержит все дочерние узлы контекстного узла; не содержит узлов атрибутов и пространств имен;
□ parent — содержит родительский узел контекстного узла, если он есть;
□ descendant — содержит все узлы-потомки контекстного узла; не содержит узлов атрибутов и пространств имен;
□ descendant-or-self — содержит контекстный узел, а также всех его потомков; не содержит узлов атрибутов и пространств имен;
□ ancestor — содержит узлы, которые являются предками контекстного узла;
□ ancestor-or-self — содержит контекстный узел, а также всех его предков;
□ following — содержит узлы, следующие за контекстным узлом, в порядке просмотра документа; не содержит его потомков; не содержит узлов атрибутов и пространств имен;
□ following-sibling — содержит братские узлы контекстного узла, которые следуют за ним в порядке просмотра документа; если контекстный узел является атрибутом или узлом пространства имен, то following-sibling не будет содержать никаких узлов;
□ preceding — содержит узлы, предшествующие контекстному узлу в порядке просмотра документа; не содержит его предков; не содержит узлов атрибутов и пространств имен;
□ preceding-sibling — содержит братские узлы контекстного узла, которые предшествуют ему в порядке просмотра документа; в случае, если контекстный узел является узлом атрибута или пространства имен, preceding-sibling не будет содержать никаких узлов;
□ attribute — содержит атрибуты контекстного узла, если он является элементом; в противном случае не содержит ничего;
□ namespace — содержит узлы пространств имен контекстного узла, если он является элементом; в противном случае не содержит ничего.
Шаг выборки вида ось::node() будет содержать все узлы, принадлежащие этой оси. Например, attribute::node() (или, сокращенно @node()) будет содержать все атрибуты текущего узла.
Для того чтобы понять, как оси навигации расположены в дереве документа, обратимся к рис. 6.9.
Рис. 6.9. Расположение в документе осей навигации
На этом рисунке не показано расположение осей атрибутов и пространств имен вследствие того, что эти оси не имеют в документе физического направления.
Каждая ось имеет базовый тип узла — это тип узла, который считается "главным" в этом направлении навигации. Этот тип устанавливается следующим образом: если ось может содержать узлы элементов, ее базовым типом является элемент, в противном случае базовым типом оси навигации является тип узлов, которые она может содержать.
Кроме того, каждой оси соответствует прямое или обратное направление просмотра, которое определяет, в каком порядке будут перебираться узлы, выбираемые этой осью. Оси навигации, которые содержат узлы, предшествующие в порядке просмотра документа контекстному узлу, имеют обратное направление просмотра, все остальные оси просматриваются в прямом порядке. Поскольку оси как self и parent не могут содержать более одного узла, порядок просмотра для них не играет никакого значения.
Базовые типы узлов и направление их просмотра можно свести в одну таблицу (табл. 6.1).
Таблица 6.1. Базовые типы узлов и направления просмотра осей навигации
| Ось навигации | Базовый тип узла | Направление просмотра |
|---|---|---|
self |
Узел элемента | Нет |
child |
Узел элемента | Прямое |
parent |
Узел элемента | Нет |
descendant |
Узел элемента | Прямое |
descendant-or-self |
Узел элемента | Прямое |
ancestor |
Узел элемента | Обратное |
ancestor-or-self |
Узел элемента | Обратное |
following |
Узел элемента | Прямое |
following-sibling |
Узел элемента | Прямое |
preceding |
Узел элемента | Обратное |
preceding-sibling |
Узел элемента | Обратное |
attribute |
Узел атрибута | Прямое |
namespace |
Узел пространства имен | Прямое |