Опубликован: 08.08.2007 | Уровень: для всех | Доступ: платный
Лекция 10:

Трансформация документа XML

< Лекция 9 || Лекция 10: 12345 || Лекция 11 >

Трансформация документа таблицей стилей

Язык XSL является приложением XML, так что фактически таблица стилей (т.е. таблица трансформаций) представляет собой документ XML. В связи с этим документ может начинаться с декларации XML, показывающей анализатору, какой версией языка документ закодирован.

Корневым элементом нашей таблицы стилей является элемент <xsl: stylesheet>:

<xsl: stylesheet version=="1.0"
xmlns:xsl=="http://www.w3.org/1999/XSL/Transform">.

Первым атрибутом этого элемента служит версия XSLT, вторым - атрибут xmlns:xsl, содержащий пространство имен для рекомендации трансформации XSL.

Этот атрибут декларирует пространство имен ХSLT. С данным пространством связан префикс xsl, так что корневым элементом фактически является элемент <stylesheet>, но он квалифицирован префиксом пространства имен xsl:. После объявления пространства имен любой элемент начинающийся с префикса xsl:, входит в состав словаря XSL.

Элемент <stylesheet> содержит три шаблона, каждый из которых вложен в элемент <template>. В таблице стилей этот элемент фактически называется <xsl:template>, так как мы включили пространство имен. У элемента <template> есть атрибут match, значением которого является образец ( pattern ) в форме выражения XPath. С ним сравнивается узел дерева, к которому применяется шаблон. Прежде всего процессору XSL надо сообщить желаемую форму вывода. Узнав ожидаемый формат вывода, процессор начнет исследовать исходный документ с корневого узла.

Образцы (patterns)

Прежде чем сделать преобразование дерева документа XML, из него следует выбрать те узлы, которые подвергнутся тому или иному преобразованию, Их можно выбирать по имени, содержимому, атрибутам и другим признакам. Условия отбора узлов задаются образцом (pattern), записанным в виде одного или нескольких выражений языка XPath 2.0. Выражения, содержащиеся в образце, объединяются вертикальной чертой |, означающей, что выбираемый узел должен удовлетворять хотя бы одному выражению образца. Вместо вертикальной черты можно записывать слово union.

В образце можно записать не всякое выражение XPath, а только путь, каждый шаг которого определяется осью, причем допускаются только три оси: child (по умолчанию), // и attribute. Это означает, что, находясь в каком-то узле, мы можем "увидеть", кроме него самого, только его атрибуты и узлы-потомки. Обратите внимание на то, что явная запись оси descendant-or-self недопустима, применяется только сокращенная запись //. Запись оси attribute:: можно сократить до одной "собачки" @, а текущий узел очень часто обозначается точкой.

Хотя образец и строится как выражение языка XPath, но его цель - не отобрать последовательность узлов, а проверить соответствие узла данному образцу. Можно сказать, что некоторый узел Node соответствует некоторому образцу pattern тогда и только тогда, когда узел Node принадлежит последовательности узлов - результату вычисления выражения //Pattern. Например, образцу person//street будут соответствовать все узлы из последовательности //person//street, а именно все узлы street, вложенные в узлы-элементы person даже через несколько промежуточных узлов.

Надо сразу же отметить, что перечисленные ограничения касаются только образцов. В других конструкциях языка XSLT можно применять выражения XPath в полном объеме.

Функции id() и key()

Образец может начинаться с вызова функции id() или функции key(). Единственным аргументом функции id() служит уникальный идентификатор узла, т.е. значение его атрибута типа ID. Например, образцу id(@xref) соответствует узел-элемент, на идентификатор которого ссылается значение атрибута xref. Образцу id(<h12>) соответствует узел-элемент с идентификатором h12, а образцу id(<h12>)//street - его потомки street любого уровня вложенности.

Функция id(), работающая с атрибутами типа ID, подвержена всем ограничениям этого типа, а именно:

  • у элемента может быть только один атрибут типа ID, значит, можно cссылаться только на этот атрибут, не говоря уже о том, что такой атрибут может вообще отсутствовать:
  • значение атрибута типа ID уникально, значит, нельзя обратиться сразу к нескольким элементам;
  • значение атрибута типа ID может быть только именем типа Name, значит, не может быть числом, содержать пробелы и многие другие символы;
  • схема, в которой определен тип ID атрибута, может оказаться недоступной для процессора XSLT и он не "узнает" тип атрибута;
  • функция id() работает только с атрибутами, но не с элементами, их содержимым и прочими узлами дерева документа;
  • для внесения новых перекрестных ссылок в документ XML надо его менять, вставляя атрибуты типа ID, что может быть нежелательно или невозможно.

Функция key() менее требовательна. Она снимает ограничения функции id(), обращаясь не к атрибуту элемента, находящегося в документе ХМL, а к атрибуту use специального элемента xsl:key, расположенного в таблице стилей. У нее два аргумента:

  • имя ключа, задаваемое строкой типа QName; это значение атрибута name элемента xsl:key, позволяющее выбрать нужный элемент xsl:key.
  • значение ключа, представляющее собой выражение, в результате вычисления которого получается последовательность из одного или нескольких атомарных значений типа xdt:anyAtomicType.
Образец с функцией key() выглядит примерно так:
key("addr", 230007)//street.

Элемент xsl:key определяет ключ и множество значений, а функция key() выбирает из этого множества те значения, что совпадают со вторым аргументом функции key(). Таким образом, при необходимости создания новых ссылок в исходном документе XML, его не надо изменить, достаточно добавить новые элементы xml:key в таблицу стилей.

< Лекция 9 || Лекция 10: 12345 || Лекция 11 >
Вадим Новицкий
Вадим Новицкий
Беларусь, Минск
Trololo Пукпрук
Trololo Пукпрук
Беларусь