□ Целое положительное число, показывающее позицию контекстного узла в контексте вычисления выражения — то есть порядковый номер узла в текущем множестве преобразования, которое было соответствующим образом упорядочено. Это число может быть получено функцией position. Позиция первого узла равна 1, позиция последнего — значению функции last.
□ Множество связанных переменных. Это множество есть множество пар вида "имя-значение", в котором имя переменной связывается со значением, присвоенным ей. Переменные не определяются в самом XPath, для этого следует использовать элемент языка XSLT xsclass="underline" variable. Переменные могут содержать как значения любого из четырех базовых типов XPath (булевый тип, строка, число, множество узлов), так и значения других типов. Например, в XSLT значению переменной можно присвоить результирующий фрагмент дерева, а расширения языка так и вовсе могут присваивать переменным объекты любых типов. Другое дело, что XPath-выражения в соответствии со стандартом не должны непосредственно работать другими типами объектов, кроме своих четырех базовых. Механизмы расширения XPath и XSLT будут рассматриваться в главе 10.
В отношении переменных важно понимать, что это не более чем объекты, доступ к которым можно получить по имени.
□ Библиотека функций, состоящая из множества функций, которые могут быть выполнены процессором. В XPath определяется базовая библиотека, функции которой должны быть реализованы в процессоре, однако эта библиотека может быть расширена. Например, XSLT определяет несколько дополнительных функций, которые также должны поддерживаться всеми XSLT-процессорами. Более того, в преобразованиях можно использовать и собственные функции расширения. Таким образом, библиотека функций контекста состоит из всех функций, доступных при вычислении выражения.
□ Множество объявлений пространств имен. Это множество связывает префиксы пространств имен с уникальными идентификаторами ресурсов (URI), которые им соответствуют.
Пути выборки
Одна из важнейших функций XPath — это выбор множеств узлов в документе. Особый вид XPath-выражений, называемый путями выборки позволяет выбирать в документе множества узлов в соответствии с самыми разнообразными критериями — по расположению, по типу, а также по выполнению одного или нескольких логических условий, называемых предикатами.
Синтаксис путей выборки во многом похож на синтаксис путей в файловых системах — сказывается то обстоятельство, что иерархическая структура данных в XML-документах очень близка к древовидной структуре каталогов. В качестве примера сравним дерево каталогов (рис. 6.1) с таким же деревом, записанным в виде XML-документа (листинг 6.1).
Рис. 6.1. Древовидная структура каталогов
<Java>
<Doc>
<ClassGenerator/>
<SchemaProcessor/>
<XMLParser>
<images/>
</XMLParser>
</Doc>
<Lib>
<Servlets>
<classes/>
<doc>
<images/>
</doc>
<lib/>
<src/>
</Servlets>
</Lib>
</Java>
В этой иерархии каталогов путь "/" соответствует корневому каталогу, путь "/Java/Lib/Servlets/src" — каталогу src. Путь из каталога Java в каталог XMLParser имеет вид "Doc/XMLParser", а путь из каталога Lib в каталог images — "Servlets/doc/images".
Перемещаться в системе каталогов можно не только вглубь, но также на верхние уровни при помощи пути "..", который осуществляет переход в родительский каталог. К примеру, для того, чтобы перейти из каталога "/Java/Lib/Servlets/doc/images" в каталог "/Java/Doc/XMLParser/images", можно воспользоваться путем "../../../../Doc/XMLParser/images".
Пути файловой системы, приведенные выше, в точности совпадают с путями выборки, которые мы бы использовали для обращения к соответствующим частям ХМL-документа. Путь выборки "/" содержит корневой узел, путь выборки "/java/Lib/Servlets/src" — элемент src, принадлежащий элементу Servlets, который принадлежит элементу Lib, который принадлежит элементу Java, находящемуся в корне элемента. Путь выборки "Doc/XMLParser" выбирает элементы XMLParser, находящиеся в элементах Doc, принадлежащих контекстному узлу.
В XPath существует два вида путей выборки — относительные и абсолютные пути. Абсолютный путь (например, "/Java/Doc/ClassGenerator") начинается ведущей косой чертой ("/") и отсчитывается от корневого узла документа, в то время как относительный путь (например, "Doc/XMLParser") отсчитывается от контекстного узла.
И абсолютный, и относительный пути выборки состоят из нескольких шагов выборки, разделенных косой чертой ("/"). Вычисление пути выборки производится последовательным выполнением составляющих его шагов. В случае абсолютного пути выборки, первый шаг выполняется относительно корневого узла дерева, в случае относительного пути — относительно контекстного узла контекста.
В файловой системе выполнить путь вида Lib/Servlets/classes означает:
□ из текущего каталога перейти в подкаталог Lib;
□ затем перейти в подкаталог Servlets;
□ и наконец — в подкаталог classes.
Для того чтобы выполнить такой же путь выборки в XML-документе, нужно
сделать следующее:
□ выполнить первый шаг, "Lib" — выбрать все дочерние элементы контекстного узла, имеющие имя "Lib";
□ затем выполнить шаг "Servlets" — для каждого из узлов, выбранных предыдущим шагом, выбрать дочерние элементы "Servlets" и объединить их в одно множество;
□ наконец, выполнить шаг "classes" — для каждого из узлов, выбранных на предыдущем этапе, выбрать дочерние элементы classes и объединить их в одно множество.
Опишем более подробно алгоритм вычисления пути выборки:
□ если путь выборки является абсолютным путем, то первый его шаг выполняется в контексте корневого узла документа, который содержит контекстный узел;
□ если путь выборки является относительным путем, то первый его шаг выполняется относительно контекстного узла;
□ каждый последующий шаг пути выборки выполняется для каждого узла множества, выбранного на предыдущем шаге, — таким образом выбирается несколько множеств, которые затем объединяются — это и есть множество, выбранное на текущем шаге.
Рассмотрим процесс выполнения пути выборки /A/B/D/G/I в следующем документе:
<A>
<B/>
<B>
<D>
<G/>
</D>
<G>
<I/>
</G>
<G/>
<G>
<I/>
<I/>
</G>
<D/>
<E/>
<F>
<H/>
</F>
</B>
<C/>
</A>
На рис. 6.2 показано логическое дерево, соответствующее этому документу.