Выбрать главу

□ Целое положительное число, показывающее позицию контекстного узла в контексте вычисления выражения — то есть порядковый номер узла в текущем множестве преобразования, которое было соответствующим образом упорядочено. Это число может быть получено функцией 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. Древовидная структура каталогов

Листинг 6.1 XML-документ

<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 показано логическое дерево, соответствующее этому документу.