6. Последний шаг, I
(рис. 6.8) выбирает для каждого из четырех элементов G
дочерние элементы I
. Первый элемент G
не имеет дочерних элементов, второй имеет один дочерний элемент I
, третий не содержит элементов и четвертый содержит два элемента I
. В итоге результатом выполнения этого шага будет множество, состоящее из 3 элементов I
.
Рис. 6.8. Пятый шаг
Пути выборки соответствует продукция LocationPath
, которая записывается следующим образом:
[XP1] LocationPath ::= RelativeLocationPath
| AbsoluteLocationPath
Эта продукция означает, что путь выборки может быть либо относительным путем, которому соответствует продукция RelativeLocationPath
, либо абсолютным путем с продукцией AbsoluteLocationPath
:
[XP2] AbsoluteLocationPath ::= '/' RelativeLocationPath?
| AbbreviatedAbsoluteLocationPath
[XP3] RelativeLocationPath ::= Step
| RelativeLocationPath '/' Step
| AbbreviatedRelativeLocationPath
Упростим LocationPath
, раскрыв дочерние продукции:
LocationPath ::= '/'
| RelativeLocationPath
| '/' RelativeLocationPath
| '//' RelativeLocationPath
Таким образом, путь выборки имеет четыре основных варианта, которые мы сейчас и разберем:
□ путь '/'
— используется для обращения к корневому узлу дерева;
□ путь вида RelativeLocationPath
— есть относительный путь выборки;
□ путь вида '/' RelativeLocationPath
— это абсолютный путь выборки, то есть относительный путь, которому предшествует '/'
;
□ путь вида '//' RelativeLocationPath
— это абсолютный путь выборки, в котором использован сокращенный синтаксис. Путь такого вида эквивалентен пути вида '/descendant-or-self:node()/' RelativeLocationPath
. Первой его частью является путь '/descendant-or-self:node()'
, который выбирает все узлы документа (кроме узлов атрибутов и пространств имен).
Главной деталью LocationPath
является относительный путь выборки, продукция которого также может быть переписана в раскрытом и упрощенном виде:
RelativeLocationPath ::= Step
| RelativeLocationPath '/' Step
| RelativeLocationPath '//' Step
В соответствии с этой продукцией, относительный путь выборки состоит из одного или нескольких шагов выборки, разделенных '/'
или '//'
. Как уже отмечалось ранее, конструкция '//'
есть сокращенный вариант от '/descendant-or-self::node()/'
. Таким образом, главным элементом пути выборки является шаг выборки.
Примеры:
□ /
— выберет корневой узел документа;
□ /а
— выберет элемент а
, находящийся в корне документа;
□ //а
— выберет множество всех элементов а
текущего документа.
Любой путь — это последовательность шагов, путь выборки — это последовательности шагов выборки, которые нужно совершить, чтобы получить искомый результат. Каждый шаг выборки состоит из трех частей.
□ Первая часть называется осью навигации — она показывает направление, в котором будет производиться выбор на данном шаге. Например, можно выбирать дочерние узлы, узлы-атрибуты или родительские узлы контекстного узла ( см. также раздел "Оси навигации" данной главы ).
□ Второй частью шага выборки является тест узла . Тест узла показывает, узлы какого типа или с какими именами должны быть выбраны на данном шаге.
□ Третья часть шага выборки — это один или несколько предикатов , логических выражений, которые фильтруют множество узлов, выбранных на данном шаге.
Проще говоря, ось навигации отвечает на вопрос "куда двигаемся?", тест узла — на вопрос "какие узлы ищем?", а предикаты — на вопрос "какими свойствами должны обладать выбираемые узлы?".
Пример
Шаг выборки attribute::href[. = 'http://www.xsltdev.ru']
состоит из оси навигации attribute
, которая выбирает атрибуты данного узла, теста узла href
, который выбирает узлы с именем href
и нулевым пространством имен, и предиката [. = 'http://www.xsitdev.ru']
, который оставляет в выбираемом множестве те узлы, текстовое значение которых равно "http://www.xsltdev.ru"
. Таким образом, на этом шаге будут выбраны все атрибуты href
текущего узла, имеющие значение "http://www.xsltdev.ru"
.
Шаг выборки соответствует EBNF-продукции Step
, а первая его часть, ось навигации — продукции AxisSpecifier
:
[XP4] Step ::= AxisSpecifier NodeTest Predicate*
| AbbreviatedStep
[XP5] AxisSpecifier ::= AxisName '::'
| AbbreviatedAxisSpecifier
Продукцию Step
можно значительно упростить и записать в следующем виде:
Читать дальше