Опубликован: 08.08.2007 | Доступ: свободный | Студентов: 1670 / 176 | Оценка: 3.86 / 3.76 | Длительность: 11:46:00
Специальности: Программист
Лекция 9:

Связи и запросы

Дерево документа

Язык XPath рассматривает документ XML как дерево. Корнем дерева будет корневой элемент документа, а узлами - вложенные элементы, содержимое элемента (текстовый узел) или его атрибуты. Кроме того, в узлах дерева могут находиться комментарии, инструкции по обработке, пространства имен.

Схема element() не учитывает текстовые узлы и узлы-атрибуты. Она отмечает только вложенные элементы. Но схема xpointer() должна строго следовать правилам языка XPath и учитывать текстовые узлы, даже если они содержат только пробельные символы. Впрочем, многие программы-анализаторы языка XPointer не следуют этому правилу. Например, функция last() разными программами-анализаторами будет вычислена по-разному в зависимости от того, как они построят дерево документа.

Дополнения языка XPointer

Исторически сложилось так, что язык XPath был создан на два года раньше языка XPoinler. Поэтому создатели языка XPointer внесли в него дополнения, расширившие конструкции языка XPath.

Во-первых, кроме узлов дерева, язык XPointer рассматривает точки (points) и области (ranges).

Точкой язык XPointer называет позицию между символами документа XML.

Область занимает пространство между двумя точками: начальной точкой и конечной точкой. Начальная и конечная точки могут располагаться в любом месте документа XML, следовательно, область может пересекать элементы документа XML, не совпадая с узлами дерева. Разумеется, начальная точка должна встретиться в документе раньше конечной точки.

Точки, области и узлы вместе образуют местоположение. В результате всякого поиска отыскивается некоторое местоположение или набор местоположений.

Во-вторых, в схему xpointer() введены новые функции range(), stringrange(), range-to(), range-inside (), here(), origin (), start-point(), end-point(), работающие с точками и областями.

Эти дополнения позволяют гораздо точнее адресовать различные части документа, вплоть до отдельного символа.

Все действия с точками и областями выполняются с помощью перечисленных функций.

Адресация на языке XPath

Для удобной работы с документом XML необходимы средства, позволяющие точно адресовать ту или иную его часть: отдельную точку, множество точек, какой-либо участок или множество участков документа. Такие средства предоставляет язык XPath, разработанный консорциумом W3C. Язык XPath, как и XPointer, - не реализация XML. Его основу составляют выражения различных типов, в числе которых логический, числовой и строковый тип. В выражениях записываются константы, переменные и функции, входящие в состав XPath. Они связываются операциями, характерными для данного типа. В результате вычисления выражения получается указание на какой-то один или сразу несколько участков документа.

Очень часто выражение строится подобно пути к файлу в файловой системе, откуда и происходит название языка "XML Path", сокращенно XPath. При этом документ XML рассматривается как дерево.

Дерево документа

Язык XPath представляет документ в виде дерева, корнем которого служит корневой элемент документа. От корня отходят ветви, заканчивающиеся узлами. Узлами служат, например, вложенные элементы, их атрибуты и тексты, составляющие содержимое корневого элемента. От каждого вложенного элемента отходят свои ветви, рекурсивно повторяющие ветви корневого элемента. Таким образом, у каждого узла может быть только один узел - "предок", причем предком может быть только узел корневого или другого элемента дерева, но не атрибут и не текстовый узел.

Узлы дерева

Язык XPath различает семь видов узлов.

  1. Узлы документа. Не отождествляйте узел документа с узлом корневого элемента документа. Узел корневого элемента вложен в узел документа наряду с узлами-комментариями и узлами инструкции по обработке. Кроме того, в языке XPath предусмотрена возможность работы с другими типами документов, возможно, содержащими несколько корневых элементов. Имя узла документа совпадает с именем корневого элемента документа.
  2. Узлы-элементы. Имя узла-элемента состоит из идентификатора пространства имен, получаемого по префиксу уточненного имени элемента, и локального имени элемента. Это расширенное имя узла. Если у элемента есть атрибут типа ID, то он служит идентификатором узла.
  3. Узлы-атрибуты. Их предок - узел-элемент, к которому относятся атрибуты, хотя они не считаются потомками этого узла. Узел-атрибут тоже определяется расширенным именем, полученным из уточненного имени атрибута.
  4. Узлы пространств имен. С каждым узлом-элементом связаны узлы тех пространств имен, в область действия которых входит данный элемент. Так же как и узлы-атрибуты, они не считаются потомками узла-элемента, хотя считают его своим предком. Поэтому программа-анализатор, обходя дерево, не будет автоматически просматривать узлы пространств имен. Имя узла пространства имен - это префикс, связанный с ним.
  5. Узлы инструкций по обработке. Это отдельные узлы, имена которых - это имена целевых приложений, выполняющих инструкцию. Первая строка пролога документа XML
    <?xml version="1.0"?>
    не считается инструкцией по обработке и не входит в дерево документа.
  6. Узлы комментарии. Каждый комментарий заносится в дерево как узел без имени.
  7. Текстовые узлы. Это строка символов, записанная в теле элемента между вложенными элементами. У текстовых узлов нет расширенного имени.

Узел любого вида можно представить строкой символов. Для каждого вида узла правила представления свои, они перечислены далее.

  • Строка, представляющая узел документа или узел-элемент, состоит из всех строк, представляющих его узлы-потомки текстового вида.
  • Строка, представляющая узел-атрибут, содержит его значение.
  • Строка, представляющая узел пространства имен, содержит его строку URI.
  • Строка узла инструкции по обработке составлена из ее содержимого.
  • Узел-комментарий и текстовый узел сами являются строками, причем начальные символы <!- и конечные символы -> комментария в строку не входят.

Выражения, определяющие путь

Чаще всего выражение языка XPath показывает путь к определяемому участку документа XML, начинающийся в корневом узле документа или каком-то начальном узле. Такие выражения состоят из нескольких шагов поиска, выполняемых последовательно слева направо. Последовательность, полученная на предыдущем шаге, передается следующему шагу, который использует ее как исходный материал для поиска. Шаги в выражении разделены наклонными чертами. Например, выражение

/contract/section/paragraph

состоит из трех шагов поиска, содержащих имена элементов contract, section и paragraph. В результате вычисления первого шага этого выражения получится последовательность узлов, вложенных в узел документа contract. На втором шаге из этой последовательности выбираются узлы section, на третьем - узлы paragraph. В результате вычисления всего выражения получается последовательность узлов, состоящая из всех элементов paragraph, вложенных в элементы section, которые, в свою очередь, вложены в элементы contract.

В общем случае шаг поиска устроен гораздо сложнее. Язык XPath 2.0 различает два вида шагов поиска: шаг, направляемый осью поиска, и шаг, направляемый фильтром. После выполнения шага, направляемого осью, получается последовательность узлов, а после выполнения фильтра в последовательности кроме узлов могут встретиться атомарные значения.

Шаг, направляемый осью поиска

Шаг, направляемый осью поиска, состоит из трех частей: оси поиска, теста узла и необязательного предиката. Ось отделяется от теста узла двумя двоеточиями, а предикат записывается после теста узла в квадратных скобках:

ось: текст узла [предикат].

Например, шаг поиска может выглядеть так:

child::section[l]

В этом примере ось поиска child показывает, что поиск охватывает все узлы, непосредственно вложенные в просматриваемый узел, за исключением узлов-атрибутов и узлов пространств имен, текст узла section выбирает из этих узлов узлы-элементы section, а предикат 1 выбирает первый из встреченных узлов-элементов section.

Каждая из трех частей шага поиска сужает первоначальную область поиска.

Ось поиска задает направление поиска, отсчитываемое от текущего узла, и его объем. Например, поиск может идти в сторону вложенных элементов или, наоборот, просматривать родительские узлы. Можно просматривать только атрибуты элементов или только соседние элементы.

Текст узла выбирает в области поиска, заданной осью, определенные узлы по их имени или типу.

Предикат содержит условия, по которым проверяет узлы, уже отобранные осью поиска и тестом узла, и делает окончательный выбор.

Шаг, направляемый фильтром

Шаг, направляемый фильтром, использует вместо оси и теста узла первичное выражение:

Первичное выражение[Предикат]

Первичное выражение выдает в качестве результата последовательность узлов и/или атомарных значений, которая затем фильтруется предикатом.

Первичное выражение - это:

  • число типа xs:integer, xs:decimal, xs:double ;
  • строка символов типа xs:string ;
  • значение переменной, начинающееся со знака доллара $;.
  • вызов функции;
  • наконец, произвольное выражение, заключенное в скобки.

Поэтому на шаге, направляемом фильтром, можно применять любое выражение, надо только заключить его в скобки.

Язык запросов XQuery

После того как язык XML научился делать ссылки на языке XLink, создавать указатели XPointer на каждую точку документа и тонко адресовать любые части документа с помощью XPath, остался последний шаг: научиться извлекать найденную по адресу информацию из любых участков документа и оформлять ее в виде элементов документа XML. Язык XQuery как раз и призван сделать этот последний шаг.

Поскольку перед извлечением информации из документа надо ее отыскать язык XQuery разрабатывался в тесной связи с языком XPath 2.0. Более того, большинство конструкций языка XPath 2.0 созданы в расчете на написание запросов. Многие выражения XPath, такие как выражение //ААА/ВВВ, делают запрос на поиск информации в документе XML. Поэтому язык XQuery можно считать расширением язык XPath 2.0. В нем можно применять почти все, что есть в языке XPath 2.0.

Единственное ограничение - в первой версии языка XQuery, выражения, определяющие путь, можно направлять только по 6 осям из 13, имеющихся в языке XPath: child (по умолчанию), descendant, attribute, self, descendant-or-self и parent.

Основной единицей языка XQuery, как и языка XPath, служит выражение, причем набор выражений, перечисленных через запятую, тоже считается выражением. Это так называемая "операция запятая", объединяющая несколько выражений в одно, вычисляемое последовательно слева направо. Результат вычисления выражения, как и в языке XPath, - последовательность узлов и/или атомарных значений. Виды узлов и типы атомарных значений таковы же, как и в XPath 2.0.

Запрос в языке XQuery тоже оформляется как выражение. Разница заключается в том, что и результате вычисления выражения получается последовательность, а в результате выполнения запроса должен получиться один или несколько документов XML. Значит, в первую очередь язык XQuery должен научиться конструировать элементы XML. За это отвечают конструкторы.

Конструкторы

Конструктор узлов - это выражение, которое создает и добавляет к дереву документа новые узлы.

Конструкторы могут создавать узлы каждого вида за исключением узлов пространств имен. При этом узел-элемент можно создать средствами прямого или вычисляемого конструктора, узел-атрибут, корневой узел документа и текстовый узел - только вычисляемого конструктора, а узлы-комментарии и узлы инструкций по обработке просто записываются в конструкторе прямо в том виде, в каком они затем появятся в документе.