Язык преобразований XSL (XSLT) 1.0-1

Рекомендация W3C от 16 ноября 1999

Данный документ представляет собой перевод спецификации XSL Transformations (XSLT) Version 1.0 (W3C Recommendation) на русский язык. При этом нормативным документом считается оригинальная спецификация на английском языке, которую можно найти по адресу http://www.w3.org/TR/1999/REC-xslt-19991116. Перевод спецификации на русский язык представлен на страницах портала "Россия-Он-Лайн": http://www.rol.ru/news/it/helpdesk/xslt01.htm Перевод выполнен Радиком Усмановым, Luxoft (IBS)
Представленный документ может содержать ошибки перевода.
Данная версия:
http://www.w3.org/TR/1999/REC-xslt-19991116
(доступна в форматах XML и HTML)
Последняя версия:
http://www.w3.org/TR/xslt
Предыдущие версии:
http://www.w3.org/TR/1999/PR-xslt-19991008
http://www.w3.org/1999/08/WD-xslt-19990813
http://www.w3.org/1999/07/WD-xslt-19990709
http://www.w3.org/TR/1999/WD-xslt-19990421
http://www.w3.org/TR/1998/WD-xsl-19981216
http://www.w3.org/TR/1998/WD-xsl-19980818
Редактор:
James Clark mailto:jjc@jclark.com

Copyright © 1999 W3C® (MIT, INRIA, Keio), Все права защищены. Обязательства W3C, правила, касающиеся торговой марки, применения документа и лицензирования программного обеспечения.


Предисловие

Данная спецификация определяет синтаксис и семантику XSLT, языка преобразований XML документов в другие XML документы.

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

Кроме того, XSLT построен так, чтобы использоваться независимо от XSL. Вместе с тем XSLT не позиционируется как полноценный универсальный язык преобразований XML. Скорее наоборот, прежде всего он предназначен для тех видов преобразований, которые необходимы когда XSLT используется как часть XSL.

Статус документа

Данный документ был рассмотрен членами W3C, другими заинтересованными сторонами и одобрен Директором в качестве Рекомендации W3C. Это окончательный документ, который можно использовать как материал для ссылки или цитирования в других документах в качестве нормативного материала. Участие W3C в разработке данной Рекомендации заключается в привлечении внимания к представленной спецификации и способствовании ее всеобщему распространению. Тем самым повышается функциональность и универсальность Сети.

Перечень ошибок, выявленных в этой спецификации, доступен по адресу http://www.w3.org/1999/11/REC-xslt-19991116-errata.

Комментарии к данной спецификации можно выслать по адресу xsl-editors@w3.org, доступен также архив комментариев. Открытое обсуждение XSL, включая XSL Transformations, происходит в почтовом списке рассылки XSL-List.

Нормативной силой наделен лишь английский вариант этой спецификации. Однако по адресу http://www.w3.org/Style/XSL/translations.html можно найти перевод этого документа на другие языки.

Перечень текущих Рекомендаций W3C, а также другие технические документы можно найти по адресу http://www.w3.org/TR.

Данная спецификация была разработана в рамках проекта W3C Style.


1 Введение

В данной спецификации определяется синтаксис и семантика языка XSLT. Преобразование в языке XSLT предстает в виде корректного (well-formed) XML документа [XML], соответствующего требованиям для пространств имен из Рекомендации XML [XML Names]. Оно может содержать как элементы, определяемые в XSLT, так и элементы, которые в XSLT не определены. Элементы, определяемые в XSLT, отличаются принадлежностью определенному пространству имен XML (см. главу [2.1 Пространство имен XSLT]), которое в данной спецификации мы называем пространством имен XSLT. Таким образом, данная спецификация - это определение синтаксиса и семантики пространства имен XSLT.

Преобразование, выраженное через XSLT, описывает правила преобразования исходного дерева документа в конечное дерево. Преобразование строится путем сопоставления образцов и шаблонов. Образец сравнивается с элементами исходного дерева, а шаблон используется для создания частей конечного дерева. Конечное дерево отделено от исходного дерева. Структура конечного дерева может полностью отличаться от структуры исходного дерева. В ходе построения конечного дерева элементы исходного дерева могут подвергаться фильтрации и переупорядочению, также может добавлена новая структура.

Преобразование, выраженное через XSLT, называется стилем (stylesheet). Так сделано потому, что в случае, когда XSLT приводится к словарю форматирования XSL, данное преобразование выполняет функции стиля.

Данный документ не конкретизирует, каким образом стиль XSLT привязывается к документу XML. Рекомендуется чтобы процессоры XSL поддерживали механизм, описанный в документе [Стиль XML]. Когда этот или какой-либо другой механизм дает последовательность из нескольких стилей XSLT, которые должны быть применены к XML-документу одновременно, это будет то же самое, как если бы использовался один стиль, поочередно импортирующий все члены этой последовательности стилей (см. [2.6.2 Импорт стилей]).

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

Чтобы получить фрагмент в конечном дереве, шаблон обрабатывается для определенного элемента в исходном документе. Шаблон может содержать элементы, определяющие фиксированную структуру конечного элемента. Шаблон может также содержать элементы из пространства имен XSLT, дающие инструкции по созданию фрагментов конечного дерева. При обработке шаблона каждая инструкция обрабатывается и заменяется на полученный фрагмент конечного дерева. Инструкции могут находить в исходном дереве и обрабатывать элементы-потомки. При обработке элемента-потомка в конечном дереве создается фрагмент путем нахождения соответствующего правила шаблона и обработки его шаблона. Заметим, что элементы обрабатываются только если они были выбраны в ходе выполнения инструкции. Конечное дерево строится после нахождения правила шаблона для корневого узла и обработки в нем шаблона.

В ходе поиска соответствующего правила шаблона может выясниться, что данному элементу соответствует не одно, а сразу несколько правил. Однако использоваться будет только одно правило шаблона. Методика для определения, какое из правил шаблона должно использоваться, описывается в разделе [5.5 Разрешение конфликтов в правилах шаблона].

Шаблон даже сам по себе наделен значительной мощностью: он может создавать структуры произвольной сложности, извлекать строковые значения из любых мест исходного дерева, создавать структуры, повторяющие появление элементов в исходном дереве. Для простых преобразований, когда структура конечного дерева не связана со структурой исходного дерева, стиль часто образуется одним шаблоном, который используется как шаблон для всего конечного дерева. К этому типу часто относится преобразование XML документов, которые содержат некие данные (см. [D.2 Пример данных]). Для таких стилей в XSLT предусмотрен упрощенный синтаксис (см. [2.3 Фиксированный конечный элемент как стиль]).

Если обрабатывается шаблон, то это всегда делается отталкиваясь от текущего узла и текущего набора узлов. Текущий узел всегда является членом текущего набора узлов. В XSLT многие операции привязаны к текущему узлу. И лишь несколько инструкций меняют текущий набор узлов или текущий узел (см. [5 Правила шаблона] и [8 Повторение]). При обработке любой из этих инструкций текущий набор узлов заменяется новым набором узлов, а каждый член этого нового набора по очереди становится текущим узлом. После того как обработка инструкции завершена, текущий узел и текущий набор узлов становится такими, каким они были до обработки этой инструкции.

Для выбора элементов для обработки, обработки при условии и генерации текста XSLT использует язык выражений, сформулированный в [XPath].

XSLT оставляет две "зацепки" для дальнейших расширений языка. Первая связана с расширением набора элементов инструкций, используемых в шаблонах, а вторая - с расширением набора функций, используемых в выражениях XPath. Обе эти зацепки основаны на использовании пространства имен XML. Механизм их реализации в данной версии XSLT не конкретизируется. См. главу [14 Расширения].

Замечание: Указанный механизм рабочая группа XSL должна определить в следующем варианте спецификации, либо в отдельной спецификации.

Для описания синтаксиса элементов, определенных в XSLT, используется общая нотация синтаксиса элементов, описаная в главе [18 Нотация].

Для стилей XSLT должен использоваться тип среды MIME text/xml или application/xml [RFC2376]. Возможно, специально для работы со стилями XSLT будет зарегистрирован еще один тип среды. Если это произойдет, то он тоже может быть использован.

2 Структура стиля

2.1 Пространство имен XSLT

Пространство имен XSLT имеет URI http://www.w3.org/1999/XSL/Transform.

Замечание: Число 1999 в этом URI показывает год, в который этот URI был принят W3C. И это не версия используемого XSLT, которая задается атрибутами (см. главы [2.2 Элемент стиля] и [2.3 Фиксированный конечный элемент как стиль]).

Чтобы идентифицировать элементы и атрибуты из указанного пространства, XSLT процессоры должны использовать механизм пространства имен XML [Имена XML]. Элементы из пространства имен XSLT распознаются только в стиле, а не в исходном документе. Полный перечень элементов, определенных в XSLT, представлен в Приложении [B Справочник синтаксиса элементов]. Разработчики не должны пополнять пространство имен XSLT дополнительными элементами и атрибутами. Вместо этого любое расширение должно быть вынесено в отдельное пространство имен. Какое бы пространство имен не использовалось для дополнительных элементов инструкций, оно должно быть идентифицировано с помощью механизма элементов расширения, описанного в главе [14.1 Элементы расширения].

Для обращения к элементам из пространства имен XSLT в данной спецификации использует префикс xsl:. Однако в XSLT стиле можно свободно использовать любой префикс при условии, что имеется декларация пространства имен, привязывающая этот префикс к тому же URI пространства имен XSLT.

Элемент из пространства имен XSLT может иметь любой атрибут из другого пространства при условии, что расширенное имя этого атрибута имеет ненулевой URI пространства имен. Появление таких атрибутов не должно изменять поведение элементов и функций XSLT, определенных в данном документе. Соответственно, XSLT процессор может всегда свободно игнорировать такие атрибуты и даже обязан это делать, не фиксируя ошибки, если найти соответствующее URI пространства имен не удается. Описанные атрибуты, к примеру, могут содержать уникальные идентификаторы, инструкции по оптимизации или документирование.

Если элемент из пространства имен XSLT имеет атрибут, чье расширенное имя имеет нулевой URI пространства имен (т.е. атрибут с названием без префиксов), и который не входит в число атрибутов, определенных для этого элемента в данном документе, фиксируется ошибка.

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

2.2 Элемент стиля

<xsl:stylesheet
id = id
;extension-element-prefixes = tokens
exclude-result-prefixes = tokens
version = number>
<!-- Content: (xsl:import*, top-level-elements) -->
</xsl:stylesheet>

<xsl:transform
id = id
extension-element-prefixes = tokens
exclude-result-prefixes = tokens
version = number>
<!-- Content: (xsl:import*, top-level-elements) -->
</xsl:transform>

В XML документе стиль представлен элементом xsl:stylesheet. В качестве синонима xsl:stylesheet можно использовать xsl:transform.

Элемент xsl:stylesheet обязан иметь атрибут version, указывающий какая версия XSLT необходима для этого стиля. Для обсуждаемой версии XSLT значение атрибута должно быть 1.0. Если значение отлично от 1.0, можно использовать режим совместимости с последующими версиями (см. главу [2.5 Обработка, совместимая с последующими версиями]).

Элемент xsl:stylesheet может содержать следующие типы элементов:

  • xsl:import

  • xsl:include

  • xsl:strip-space

  • xsl:preserve-space

  • xsl:output

  • xsl:key

  • xsl:decimal-format

  • xsl:namespace-alias

  • xsl:attribute-set

  • xsl:variable

  • xsl:param

  • xsl:template

Элемент, оказавшийся непосредственным потомком элемента xsl:stylesheet, называется элементом верхнего уровня.

Следующий пример показывает структуру стиля. Многоточием (...) обозначены те места, где опущено значение атрибута или содержимое. Хотя в этом примере показано по одному элементу для каждого разрешенного типа, стиль может не содержать какой-либо из этих элементов, либо содержать сразу несколько его экземпляров.

<xsl:stylesheet version="1.0"

        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="..."/>

  <xsl:include href="..."/>

  <xsl:strip-space elements="..."/>
  
  <xsl:preserve-space elements="..."/>

  <xsl:output method="..."/>

  <xsl:key name="..." match="..." use="..."/>

  <xsl:decimal-format name="..."/>

  <xsl:namespace-alias stylesheet-prefix="..." 
  result-prefix="..."/>

  <xsl:attribute-set name="...">
    ...
  </xsl:attribute-set>

  <xsl:variable name="...">...</xsl:variable>

  <xsl:param name="...">...</xsl:param>

  <xsl:template match="...">
    ...
  </xsl:template>

  <xsl:template name="...">
    ...
  </xsl:template>

</xsl:stylesheet>

Порядок появления непосредственных потомков элемента xsl:stylesheet значения не имеет, за исключением элементов xsl:import и обработки ошибки. Пользователи могут располагать элементы по своему усмотрению, а инструментам разработи стилей нет нужды контролировать порядок размещения указанных элементов.

Кроме этого, элемент xsl:stylesheet может содержать любой элемент не из пространства имен XSLT, при условии что расширенное имя этого элемента содержит ненулевой URI пространства имен. Появление таких элементов верхнего уровня не должно сказываться на поведении элементов и функций XSLT, определенных в данном документе. Например, такой элемент верхнего уровня не может заставить xsl:apply-templates использовать другие правила для разрешения конфликтов. Таким образом, XSLT процессор всегда может свободно игнорировать такие элементы верхнего уровня. Более того, процессор обязан игнорировать элемент верхнего уровня, не инициируя ошибки, если не может распознать в нем URI пространства имен. К примеру, такие элементы могут содержать

  • информацию, используемую элементами или функциями расширения (см. [14 Расширения]),

  • информацию о том что следует делать с конечным деревом,

  • информацию о том как получить исходное дерево,

  • метаданные о представленном стиле,

  • структурированную документацию для этого стиля.

2.3 Фиксированный конечный элемент как стиль

Для стилей, состоящих из единственного шаблона, для корневого узла можно использовать упрощенный синтаксис. Данный стиль может содержать только один фиксированный конечный элемент (literal result element, см. главу [7.1.1 Фиксированные конечные элементы]). Такой стиль равнозначен стилю с элементом xsl:stylesheet, содержащим правило шаблона с фиксированным конечным элементом, которое для сравнения использует образец /. Например:

<html xsl:version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns="http://www.w3.org/TR/xhtml1/strict">
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
   <p>Total Amount: 
   <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>

что равнозначно

<xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns="http://www.w3.org/TR/xhtml1/strict">
<xsl:template match="/">
<html>
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
    <p>Total Amount: 
    <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>
</xsl:template>
</xsl:stylesheet>

Фиксированный конечный элемент, являющийся для стиля элементом документа, должен иметь атрибут xsl:version, указывающий версию XSLT, необходимую для этого стиля. Для данной версии XSLT значением этого атрибута должно быть 1.0, значение должно иметь тип Number. Другие фиксированные конечные элементы также должны иметь атрибут xsl:version. Если атрибут xsl:version не равен 1.0, должен быть разрешен режим обработки, совместимый с последующими версиями. (см. главу [2.5 Обработка, совместимая с последующими версиями]).

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

В некоторых ситуациях, единственная возможность для системы узнать, что некий XML документ XSLT процессор должен обрабатывать именно как стиль XSLT - это исследовать сам представленный XML документ самостоятельно. Использование упрощенного синтаксиса усложняет эту задачу.

Замечание: Например, другой язык XML (AXL) также может использовать в элементе документа атрибут axl:version чтобы показать, что XML документ является AXL документом, который необходимо обрабатывать AXL процессором. Если документ имеет оба указанных атрибута axl:version, становится непонятным, следует ли данный документ обрабатывать XSLT процессором или же AXL процессором.

По этой причине упрощенный синтаксис не должен использоваться для XSLT стилей, которые могут оказаться в такой ситуации. Например, такая ситуация может возникать когда стиль XSLT передается как сообщение с типом среды MIME text/xml или application/xml, а получатель использует этот тип среды MIME чтобы определить, как следует обрабатывать это сообщение.

2.4 Полные имена

Название внутреннего объекта XSLT, а именно: именованного шаблона (см. [6 Именованные шаблоны]), режима (см. [5.7 Режимы]), набора атрибутов (см. [7.1.4 Именованные наборы атрибутов]), ключа (см. [12.2 Ключи]), десятичного формата (см. [12.3 Форматирование чисел]), переменной или параметра (см. [11 Переменные и параметры]), задается как QName. Если название имеет префикс, то этот префикс преобразуется в ссылку URI с помощью деклараций пространства имен, в области действия оказался атрибут с этим названием. В качестве названия указанного объекта используется расширенное имя, состоящее из локальной части и, возможно нулевой, ссылки URI. Для названий без префиксов пространство имен по умолчанию не используется.

2.5 Обработка, совместимая с последующими версиями

Режим совместимости с последующими версиями можно использовать для самого элемента, его атрибутов, его потомков и их атрибутов, если имеется элемент xsl:stylesheet с атрибутом version, значение которого отлично от 1.0, или имеется фиксированный конечный элемент, имеющий атрибут xsl:version со значением, отличным от 1.0, либо имеется фиксированный конечный элемент, не имеющий атрибута xsl:version, но элемент документа в стиле использует упрощенный синтаксис (см. [2.3 Фиксированный конечный элемент как стиль]). Фиксированный конечный элемент, имеющий атрибут xsl:version, значение которого равно 1.0, отменяет режим совместимости с последующими версиями для себя, своих атрибутов, своих потомков и их атрибутов.

Если элемент обрабатывается в режиме совместимости с последующими версиями, то:

  • если есть некий элемент верхнего уровня, а XSLT 1.0 такие элементы не позволяет использовать в качестве элементов верхнего уровня, то такой элемент и его содержимое должны быть проигнорированы;

  • если в шаблоне есть некий элемент, а XSLT 1.0 не позволяет в шаблонах использовать такие элементы, то когда этот элемент не обрабатывается, сообщения об ошибке возникать не должно, если же этот элемент уже был обработан, то XSLT должен выполнить откат для этого элемента как описано в главе [15 Откат];

  • если элемент имеет атрибут, который XSLT 1.0 ему иметь не позволяет, или если элемент имеет необязательный атрибут со значением, которое XSLT 1.0 также не позволяет ему иметь, такой атрибут должен быть проигнорирован.

Таким образом, любой процессор XSLT 1.0 должен уметь обработать представленный далее стиль без ошибок, даже несмотря на то, что тот содержит элементы из пространства имен XSLT, которые не были заданы в этой спецификации:

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

  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="system-property('xsl:version') >= 1.1">
        <xsl:exciting-new-1.1-feature/>
      </xsl:when>
      <xsl:otherwise>
        <html>
        <head>
          <title>XSLT 1.1 required</title>
        </head>
        <body>
          <p>Sorry, this stylesheet requires XSLT 1.1.</p>
        </body>
        </html>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Замечание: Если стиль опосредованно зависит от элемента верхнего уровня, объявленного в XSL более старшей версии чем 1.0, то тогда в этом стиле можно использовать элемент xsl:message с атрибутом terminate="yes" (см. [13 Сообщения]) чтобы гарантировать, что XSLT процессоры, реализующие более ранние версии XSL, не будут втихую игнорировать указанный элемент верхнего уровня. Например,

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

  <xsl:important-new-1.1-declaration/>

  <xsl:template match="/">
    <xsl:choose>
      <xsl:when

      test="system-property('xsl:version') &lt; 1.1">
      <xsl:message terminate="yes">
        <xsl:text>Sorry, this stylesheet requires XSLT 1.1.

        </xsl:text>
        </xsl:message>
      </xsl:when>
      <xsl:otherwise>
        ...
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  ...
</xsl:stylesheet>

Если выражение встретилось в атрибуте, который обрабатывается в режиме совместимости со следующими версиями, то ошибки XSLT процессор должен обрабатывать следующим образом:

  • если выражение не соответствует синтаксису, заданному грамматикой XPath, то ошибка не должна фиксироваться до тех пор, пока реально не будет затребована обработка этого выражения;

  • если выражение вызывает функцию с названием без префикса, которая не является частью библиотеки XSLT, то ошибка не должна фиксироваться до тех пор, пока данная функция не будет действительно вызвана;

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

2.6 Комбинированные стили

Язык XSLT предоставляет два механизма для комбинирования стилей:

  • механизм включения (include), позволяющий объединять стили без изменения семантики комбинированных стилей, и
  • механизм импорта (import), который позволяет стилям переписывать друг друга.

2.6.1 Включение стилей

<!-- Category: top-level-element -->
<xsl:include
href = uri-reference />

С помощью элемента xsl:include< один стиль XSLT может включить в себя другой стиль XSLT. Элемент xsl:include имеет атрибут href, значением которого является ссылка URI, идентифицирующая включаемый стиль. Относительная ссылка URI обрабатывается относительно базового URI элемента xsl:include (см. [3.2 Базовый URI]).

Элемент xsl:include можно использовать лишь в качестве элемента верхнего уровня.

Включение оперирует деревьями XML. Ресурс, на который указывает атрибут href, обрабатывается как документ XML и обнаруженные в нем непосредственные потомки элемента xsl:stylesheet замещают элемент xsl:include во включающем документе. Тот факт, что те или иные правила шаблона или определения были получены включением, на то как они затем обрабатываются не влияет.

Во включаемом стиле может использоваться упрощенный синтаксис, описанный в главе [2.3 Фиксированный конечный элемент как стиль]. Включаемый стиль обрабатывается точно так же как эквивалентный ему элемент xsl:stylesheet.

Если стиль прямо или опосредовано включает сам себя, фиксируется ошибка.

Замечание: Многократное включение стиля может привести к ошибкам вследствие дублирования деклараций. Такие множественные включения не столь очевидны, если являются косвенными. Например, если стиль B включает стиль A, стиль C включает стиль A, а стиль D включает оба стиля B и C, то A опосредованно включено в D дважды. Если все указанные стили B, C и D являются независимыми, то ошибки можно избежать, если в B выделить все, что не относится к включенному A, в отдельный стиль B' и поменять B так чтобы он просто включал эти B' и A, затем аналогично поступить с C, и, наконец, переписать D так чтобы он включал A, B' и C'.

2.6.2 Импорт стилей

<xsl:import
href = uri-reference />

С помощью элемента xsl:import один XSLT стиль может импортировать другой стиль XSLT. Импортирование стиля похоже на его включение (см. [2.6.1 Включение стилей]) за исключением того, что определения и правила шаблона в испортирующем стиле имеют приоритет над правилами шаблона и определениями в импортируемом стиле, более детально это будет обсуждаться ниже. Элемент xsl:import имеет атрибут href, значением которого является ссылка URI, идентифицирующая импортируемый стиль. Относительная ссылка URI обрабатывается относительно базового URI элемента xsl:import (см. [3.2 Базовый URI]).

Элемент xsl:import можно использовать только как элемент верхнего уровня. Потомки элемента xsl:import должны предшествовать всем другим элементам, являющимся непосредственными потомкам элемента xsl:stylesheet, в том числе и всем элементам xsl:include. Если для включения стиля используется xsl:include, то все элементы xsl:import из включаемого документа в включающем документе переносятся вверх и ставятся после всех уже имевшихся во включающем документе элементов xsl:import.

Например,

<xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="article.xsl"/>
  <xsl:import href="bigfont.xsl"/>
  <xsl:attribute-set name="note-style">
    <xsl:attribute name="font-style">italic</xsl:attribute>
  </xsl:attribute-set>
</xsl:stylesheet>

Элементы xsl:stylesheet, которые встречаются при обработке стиля, содержащего элементы xsl:import, обрабатываются как формирующие дерево импорта. В дереве импорта каждый элемент xsl:stylesheet имеет одного импортируемого непосредственного потомка для каждого элемента xsl:import, который он содержит. Элементы xsl:include обрабатываются до начала построения дерева импорта. Элемент xsl:stylesheet в дереве импорта по определению имеет меньший приоритет импорта чем другой элемент xsl:stylesheet в дереве импорта, если он будет посещен прежде этого элемента xsl:stylesheet при проходе дерева импорта после обработки (то есть, таком проходе дерева импорта, когда элемент xsl:stylesheet посещается после своего импортированного непосредственного потомка). Каждое определение и правило шаблона имеет приоритет импорта, заданный элементом xsl:stylesheet, в котором он содержится.

Например, предположим, что

  • стиль A, импортирует стили B и <C в указанном порядке:

  • стиль B импортирует стиль D;

  • стиль C импортирует стиль E.

Тогда порядок приоритетов импорта (начиная с наименьшего) будет D, B, E, C и A.

Замечание: Поскольку элементы xsl:import должны располагаться прежде любых определений и правил шаблона, то реализация, которая обрабатывает импортированные стили в той точке, где встретился, соответствующий элемент xsl:import будет встречать определения и правила шаблона в порядке увеличения приоритета импортирования.

В общем случае, определение или правило шаблона с более высоким приоритетом импорта имеет главенство над определениями или правилами шаблона с более низким приоритетом импорта. Это выполняется в точности для каждого типа определений и правил шаблона.

Если стиль прямо или косвенно импортирует себя, фиксируется ошибка. Однако когда стиль с заданным URI импортирован сразу в нескольких местах, какой-либо специальной обработки нет. Для каждой точки, где оно было импортировано, дерево импорта будет иметь отдельный xsl:stylesheet.

Замечание: Если используется xsl:apply-imports (см. главу [5.6 Переопределение правил шаблона]), то функционирование может быть иным, чем когда этот стиль был импортирован только в этом месте и с наивысшим приоритетом импорта.

2.7 Встроенные стили

Обычно стиль XSLT является полноценным XML документом с элементом xsl:stylesheet в качестве элемента документа. Однако стиль XSLT может вынесен и в другой источник. Возможны два варианта размещения:

  • стиль XSLT может быть помещен как текст в источник, имеющий формат, отличный от XML, либо
  • элемент xsl:stylesheet может появиться в XML документе, но не в качестве элемента документа.

Чтобы содействовать второму варианту размещения, элемент xsl:stylesheet может иметь атрибут ID, который задает уникальный идентификатор.

Замечание: Чтобы такой атрибут можно было использовать с функцией id из XPath, он реально должен быть декларирован в DTD как ID.

Следующий пример показывает, каким образом можно использовать инструкцию обработки xml-stylesheet [Стиль XML] чтобы позволить документу содержать свой собственный стиль. Чтобы найти элемент xsl:stylesheet, ссылка URI использует относительный URI с идентификатором фрагмента:

<?xml-stylesheet type="text/xml" href="#style1"?>

<!DOCTYPE doc SYSTEM "doc.dtd">

<doc>

  <head>

    <xsl:stylesheet id="style1" version="1.0"

    xmlns:xsl=http://www.w3.org/1999/XSL/Transform

    xmlns:fo="http://www.w3.org/1999/XSL/Format">

      <xsl:import href="doc.xsl"/>

      <xsl:template match="id('foo')">

        <fo:block font-weight="bold">

      <xsl:apply-templates/>

        </fo:block>

      </xsl:template>

      <xsl:template match="xsl:stylesheet">

      <!-- игнорируется -->

      </xsl:template>

    </xsl:stylesheet>

  </head>

  <body>

    <para id="foo"> ... </para>

  </body>

</doc>

Замечание: Стиль, который вложен в документ, к которому должен быть применен, либо стиль, включенный или импортированный в такой стиль, как правило, должен иметь правило шаблона, сообщающее, что элементы xsl:stylesheet должны быть проигнорированы.

3. Модель данных

Используемая в XSLT модель данных аналогична используемой в XPath с определенными дополнениями, описанными в этом разделе. XSLT оперирует с исходными, конечными документами и документами стилей, используя одну и ту же модель данных. Любые два XML документа, имеющие одно и то же дерево, будут обрабатываться XSLT одинаковым образом.

Инструкции обработки и комментарии в стиле игнорируются: стиль обрабатывается так, как если бы в представляющем его дереве не было представлено ни узлов инструкций обработки, ни узлов комментариев.

3.1 Непосредственный потомок корневого узла

Обычные ограничения для непосредственного потомка корневого узла на конечное дерево не распространяется. Конечное дерево может иметь в качестве непосредственных потомкоы любую последовательность узлов, которые можно использовать как узел элемента. В частности, оно может иметь непосредственным потомком текстовый узел и любое количество узлов элементов. Если вывод осуществляется с помощью метода output из XML (см. главу [16 Вывод]), то может оказаться, что конечное дерево не является корректным XML документом. Однако оно корректной внешней общей разобранной сущностью будет всегда.

Если исходное дерево создано разбором корректного XML документа, корневой узел в исходном дереве автоматически удовлетворяет обычным ограничениям: непосредственным потомком не может быть текстовый узел, а может быть только один элемент. Когда исходное дерево создано как-нибудь иначе, например, с помощью DOM, то обычные ограничения ни на исходное дерево, ни на конечное не действуют.

3.2 Базовый URI

С каждым узлом связан URI, называемый его базовым URI, который используется для преобразования значений атрибутов, являющихся относительными URI, в абсолютные URI. Если элемент или инструкция обработки найдены во внешней сущности, то базовым URI для такого элемента или инструкции обработки будет URI этой внешней сущности. В противном случае базовым является URI самого документа. Базовым URI для узла документа является URI сущности документа. Базовым URI для текстового узла, узла комментария, узла атрибута и узла пространства имен является базовый URI родителя этого узла.

3.3 Неразобранные сущности

Корневой узел имеет схему отображения, которая определяет URI для каждой неразобранной сущности, декларированной в DTD данного документа. Этот URI создается из системного идентификатора и публичного идентификатора, указанного в декларации сущности. Чтобы для сущности найти URI, XSLT процессор может воспользоваться публичным идентификатором, вместо того чтобы обращаться к URI, указанному в системном идентификаторе. Если XSLT процессор для построения данного URI не пользуется публичным идентификатором, то он обязан воспользоваться системным идентификатором. Если системный идентификатор является относительным URI, он должен быть преобразован в абсолютный URI, используя в качестве базового URI того ресурса, который содержит декларацию данной сущности [RFC2396].

3.4 Удаление пробельных символов

После построения дерева исходного документа или документа стиля, но перед какой-либо его обработкой XSLT процессором, выполняется очистка (stripping) некоторых текстовых узлов. Текстовый узел вычищается только тогда, когда он содержит одни пробельные символы. При очистке текстовый узел удаляется из дерева документа. На вход процедура очистки получает перечень названий элементов, для которых следует сохранить пробельные символы. Процедура очистки применяется как для стилей, так и для исходных документов, однако перечень названий элементов, сохраняющих пробельные символы, для стилей и исходных документов определяется отдельно.

Текстовый узел сохраняется если имеет место какое-либо из следующих условий:

  • Название элемента, являющегося родителем данного текстового узла, находится в перечне названий элементов, сохраняющих пробельные символы.

  • Текстовый узел содержит хотя бы один непробельный символ. Как и в XML, пробельным символом считаются #x20, #x9, #xD и #xA.

  • Элемент, являющийся предком этого текстового узла, имеет атрибут xml:space со значением preserve и нет более близких элементов-предков, имеющих xml:space со значением default.

В остальных случаях текстовый узел вычищается.

Атрибуты xml:space из дерева не вычищаются.

Замечание: Это подразумевает, что если для фиксированного конечного элемента был указан атрибут xml:space, то он будет включен в результат.

В случае со стилями перечень названий элементов, сохраняющих пробельные символы, состоит лишь из xsl:text.

<!-- Category: top-level-element -->
<xsl:strip-space
elements = tokens />

<!-- Category: top-level-element -->
<xsl:preserve-space
elements = tokens />

Для исходных документов перечень названий элементов, сохраняющих пробельные символы, задается элементами верхнего уровня xsl:strip-space и xsl:preserve-space. Каждый из этих элементов имеет атрибут elements, значением которого является перечень NameTest-ов (через пробельный символ). Изначально набор названий элементов, сохраняющих пробельные символы, содержит названия всех элементов. Если название элемента совпадает с NameTest в элементе xsl:strip-space, то он удаляется из перечня названий элементов, сохраняющих пробельные символы. Если название элемента совпадает с NameTest в элементе xsl:preserve-space, то оно добавляется к перечню названий элементов, сохраняющих пробельные символы. Элемент соответствует NameTest тогда и только тогда, когда процедура сравнения узлов из XPath для NameTest и этого узла дает результат true. Конфликты между соответствием элементам xsl:strip-space и xsl:preserve-space разрешаются так же как конфликты между правилами шаблона (см. [5.5 Разрешение конфликтов в правилах шаблона]). Таким образом, образец, соответствующий заданному названию элемента, определяется следующим образом:

  • Во-первых, любой образец, имеющий по отношению к другому образцу меньший приоритет импорта, игнорируется.

  • Далее, любой образец с NameTest, который имеет более низкий приоритет по умолчанию, чем приоритет по умолчанию у NameTest для другого образца, игнорируется.

Если и после этого остается более одного образца, соответствующего названию элемента, фиксируется ошибка. XSLT процессор может фиксировать ошибку. Если он этого не делает, то должен обработать ее сам, выбрав среди оставшихся соответствующих названию элемента образцов тот, который в этом стиле был найден последним.

4 Выражения

XSLT использует язык выражений, сформулированный в XPath [XPath]. Выражения в XSLT используются для таких целей, как:

  • выбор узлов для обработки;
  • формулирование условий для разных вариантов обработки узла;
  • генерация текста для подстановки в конечное дерево.

Выражение должно соответствовать сценарию Expr из XPath.

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

Внешнее выражение в XSLT (т.е. выражение, не являющееся частью какого-либо другого выражения) получает свой контекст следующим образом:

  • узел контекста получается из текущего узла

  • положение в контексте определяется положением текущего узла в текущем наборе узлов, первая позиция имеет индекс 1

  • размер контекста определяется размером текущего набора узлов

  • привязка переменных контекста - это привязка в пределах видимости того элемента, которому принадлежит атрибут с рассматриваемым выражением (см. [11 Переменные и параметры])

  • набор деклараций пространства имен - это те декларации, в области видимости которых находится элемент, содержащий атрибут с рассматриваемым выражением. Сюда относится также неявная декларация префикса xml, обязательная согласно W3C Namespaces Recommendation [XML Names]. Пространство имен по умолчанию (декларируемое в xmlns) к этому набору деклараций не относится

  • используемая библиотека функций формируется из основной библиотеки функций, дополнительных функций, описанных в главе [12 Дополнительные функции], а также функций расширения, описанных в главе [14 Расширения]. Если в выражении появится вызов какой-либо другой функции, зафиксируется ошибка.

5 Правила шаблона

5.1 Схема обработки

Чтобы в конечном дереве построить фрагмент, обрабатывается перечень исходных узлов. Само конечное дерево строится путем обработки набора, состоящего из одного корневого узла. Перечень исходных узлов обрабатывается посредством помещения в конечное дерево структуры, созданной путем последовательной обработки каждого члена в этом перечне. Обработка узла осуществляется путем нахождения всех правил шаблона, чей образец соответствуют этому узлу, и выбора среди них самого лучшего. Затем обрабатывается шаблон из выбранного правила, причем в качестве текущего узла берется обрабатываемый узел, а как текущий набор узлов используется обрабатываемый перечень исходных узлов. Обычно шаблон содержит инструкции, которые набирают новый набор исходных узлов для дальнейшей обработки. Процесс сравнения, подстановки и нового набора продолжается рекурсивно до тех пор, пока для обработки можно найти новые исходные узлы.

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

... | Следующая глава >>

ROL.RU