<I/>
</G>
<G/>
<G>
<I/>
<I/>
</G>
<D/>
<E/>
<F>
<H/>
</F>
</B>
<C/>
</A>
На рис. 6.2 показано логическое дерево, соответствующее этому документу.
Рис. 6.2. Логическое дерево, представляющее XML-документ
Для того чтобы лучше понять процесс выбора, проследим по шагам за тем, как будет обрабатываться этот путь.
1. Данный путь (рис. 6.3) является абсолютным путем выборки, значит, он должен выполняться, начиная от корневого узла.
Рис. 6.3. Начальный узел пути выборки
2. Первым шагом пути (рис. 6.4) является шаг A, который выбирает все дочерние элементы A контекстного узла.
Рис. 6.4. Первый шаг
3. Вторым шагом пути (рис. 6.5) является шаг B, который выбирает все дочерние элементы в узлов множества, выбранного на предыдущем шаге. Так как тогда был выбран единственный узел A, текущий шаг выберет два дочерних элемента в этого узла.
Рис. 6.5. Второй шаг
4. На очередном шаге (рис. 6.6) мы выбираем дочерние элементы D. Как можно заметить, один из элементов в, выбранных на прошлом этапе, не содержит таких элементов, значит, в этом случае, шаг выборки возвратит пустое множество. Второй элемент B имеет три дочерних элемента B. В итоге мы получим множество, состоящее из трех элементов D.
Рис. 6.6. Третий шаг
5. Следующий шаг, G (рис. 6.7) выбирает дочерние элементы G. Первый элемент D, выбранный на прошлом шаге, включает один элемент G, второй не имеет таких элементов, третий — имеет три дочерних элемента G. Таким образом, на данном шаге будет выбрано множество, состоящее из четырех элементов G.
Рис. 6.7. Четвертый шаг
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: