Данный документ является переводом Рекомендации W3C XSL Transformations (XSLT) Version 1.0 от 16 ноября 1999 года и может содержать ошибки перевода. Оригинальная версия данного документа на английском языке является единственной нормативной версией и находится по адресу: http://www.w3.org/TR/1999/REC-xslt-19991116.
Автор перевода: Александр Пирамидин <a_pyramidin@yahoo.com>.

W3C

Язык преобразований XSL (XSLT)
Версия 1.0

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

Данная версия:
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 <jjc@jclark.com>

Резюме

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

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

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

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

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

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

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

Английская версия данной спецификации является единственной нормативной версией. Переводы данной спецификации можно найти на http://www.w3.org/Style/XSL/translations.html.

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

Данная спецификация была создана как часть работы W3C над Стилями.

Оглавление

1 Введение
2 Структура Таблицы Стилей
    2.1 Пространство Имён XSLT
    2.2 Элемент Stylesheet
    2.3 Литеральный Результирующий Элемент как Таблица Стилей
    2.4 Квалифицированные Имена
    2.5 Вперёд-Совместимая Обработка
    2.6 Комбинирование Таблиц Стилей
        2.6.1 Подключение
        2.6.2 Импорт
    2.7 Внедрение Таблиц Стилей
3 Модель Данных
    3.1 Потомки Корневого Узла
    3.2 Базовый URI
    3.3 Неразбираемые Экземпляры
    3.4 Вырезание Пробелов
4 Выражения
5 Шаблонные Правила
    5.1 Модель Процессинга
    5.2 Патэрны
    5.3 Определение Шаблонных Правил
    5.4 Применение Шаблонных Правил
    5.5 Разрешение Конфликтов Шаблонных Правил
    5.6 Переопределение Шаблонных Правил
    5.7 Режимы
    5.8 Встроенные Шаблонные Правила
6 Именованные Шаблоны
7 Создание Результирующего Дерева
    7.1 Создание Элементов и Атрибутов
        7.1.1 Литеральные Результирующие Элементы
        7.1.2 Создание Элементов с Помощью xsl:element
        7.1.3 Создание Атрибутов с Помощью xsl:attribute
        7.1.4 Именованные Наборы Атрибутов
    7.2 Создание Текста
    7.3 Создание Инструкций Процессинга
    7.4 Создание Комментариев
    7.5 Копирование
    7.6 Обсчёт Сгенерированного Текста
        7.6.1 Генерация Текста с Помощью xsl:value-of
        7.6.2 Шаблоны Значений Атрибутов
    7.7 Нумерация
        7.7.1 Атрибуты Конвертации Чисел в Строки
8 Повторение
9 Условный Процессинг
    9.1 Условный Процессинг с Помощью xsl:if
    9.2 Условный Процессинг с Помощью xsl:choose
10 Сортировка
11 Переменные и Параметры
    11.1 Фрагменты Результирующего Дерева
    11.2 Значения Переменных и Параметров
    11.3 Использование Значений Переменных и Параметров с Помощью xsl:copy-of
    11.4 Переменные и Параметры Верхнего Уровня
    11.5 Переменные и Параметры Внутри Шаблона
    11.6 Передача Параметров в Шаблоны
12 Дополнительные Функции
    12.1 Несколько Документов-Источников
    12.2 Ключи
    12.3 Форматирование Чисел
    12.4 Прочие Дополнительные Функции
13 Сообщения
14 Расширения
    14.1 Расширение Элементов
    14.2 Расширение Функций
15 Откат
16 Вывод
    16.1 Метод Вывода XML
    16.2 Метод Вывода HTML
    16.3 Метод Вывода Text
    16.4 Отключение Escap-ироавания в Выводе
17 Соответствие
18 Нотация

Приложения

A Ссылки
    A.1 Нормативные Ссылки
    A.2 Прочие Ссылки
B Синтаксис Элементов. Резюме.
C Фрагмент ОТД для Таблиц Стилей XSLT (ненормативное)
D Примеры (ненормативное)
    D.1 Документ
    D.2 Данные
E Благодарности (ненормативное)
F Изменения, Сделанные После Появления Предлагаемых Рекомендаций (ненормативное)
G Возможности, Предусматриваемые для Будущих Версий XSLT (ненормативное)

1 Введение

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

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

Трансформация, выраженная в XSLT, называется "таблица стилей"/stylesheet. Это сделано так, потому что в случае, когда XSLT трансформирует в словарь форматирования XSL, трансформация функционирует как таблица стилей.

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

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

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

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

Шаблон сам по себе имеет значительную мощь: он может создавать структуры произвольной сложности; он может выталкивать строковые значения из произвольного места в дереве-источнике; он может генерировать структуры, повторяющиеся в соответствии с появлением элементов в дереве-источнике. В простых трансформациях, где структура результирующего дерева независима от структуры дерева-источника, таблица стилей может часто состоять только из простого шаблона, который функционирует как шаблон для полного результирующего дерева. Трансформации документов XML, представляющих данные, часто имеют этот тип (см. [D.2 Пример с Данными]). XSLT допускает упрощённый синтаксис для таких таблиц стилей (см. [2.3 Литеральный Результирующий Элемент Как Таблица Стилей]).

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

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

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

ПРИМЕЧАНИЕ: Рабочая Группа XSL предполагает определить такой механизм в будущей версии этой спецификации или в отдельной спецификации.

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

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

2 Структура Таблицы Стилей

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

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

ПРИМЕЧАНИЕ: Цифра 1999 в URI обозначает год, когда W3C разместил данный URI. Она не обозначает используемую версию XSLT, которая специфицируется атрибутом (см. [2.2 Элемент Stylesheet] и [2.3 Литеральный Результирующий Элемент Как Таблица Стилей]).

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

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

Элемент из пространства имён XSLT может иметь любой атрибут не из пространства имён XSLT, предполагая, чтобы expanded-name/расширенное имя атрибута имеет ненулевой URI пространства имён. Наличие таких атрибутов не должно изменять поведение элементов и XSLT, определённых в данном документе. Таким образом, процессор XSLT всегда свободно может игнорировать такие атрибуты и обязан игнорировать такие атрибуты без выдачи ошибки, если он не распознаёт URI пространства имён. Такие атрибуты могут, например, предоставлять уникальные идентификаторы, подсказки по оптимизации или документацию.

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

ПРИМЕЧАНИЕ: соглашения, используемые для имён элементов, атрибутов и XSLT, таковы: все эти имена вводятся в нижнем регистре, дефисы используются для разделения слов и аббревиатуры используются, только если они появляются в синтаксисе соответствующего языка, такого как XML или HTML.

2.2 Элемент Stylesheet

<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:transform допускается как синоним для xsl:stylesheet.

Элемент xsl:stylesheet обязан иметь атрибут version, обозначающий требуемую для таблицы стилей версию XSLT. Для данной версии XSLT значение должно быть 1.0. Если значение не равно 1.0, то задействована forwards-compatible/вперёд-совместимая модель обработки (см. [2.5 Вперёд-Совместимая Обработка]).

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

Элемент, являющийся дочерним относительно элемента xsl:stylesheet, называется элементом top-level/верхнего уровня.

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

<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 пространства имён. Такие элементы могут, например предоставлять:

2.3 Литеральный Результирующий Элемент Как Таблица Стилей

Упрощённый синтаксис допускается для таблиц стилей, состоящих только из одного шаблона корневого узла. Таблица стилей может состоять только из литерального результирующего элемента (см. [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 Forwards-Compatible/Вперёд-Совместимая Обработка]).

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

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

ПРИМЕЧАНИЕ: например, другой язык XML - AXL - может также использовать axl:version в элементе документа для обозначения того, что документ XML это документ AXL, требующий обработки процессором AXL; если документ имеет оба атрибута - axl:version и xsl: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-ссылки с использованием действующих для атрибута объявлений пространств имён, в которых появляется имя. expanded-name/расширенное имя, состоящее из локальной части имени и, возможно, нулевой URI-ссылки, и используется как имя объекта. Пространство имён по умолчанию не используется для имён без префиксов.

2.5 Вперёд-Совместимая/Forwards-Compatible Обработка

Элемент включает режим forwards-compatible для себя, своих атрибутов, своих потомков и их атрибутов, если это элемент xsl:stylesheet, чей атрибут version не эквивалентен 1.0, или если это литеральный результирующий элемент, который имеет атрибут xsl:version со значением, не эквивалентным 1.0, или если это литеральный результирующий элемент, который не имеет атрибута xsl:version, и это элемент документа в таблице стилей, использующий упрощённый синтаксис (см. [2.3 Литеральный Результирующий Элемент Как Таблица Стилей]). Литеральный результирующий элемент с атрибутом  xsl:version, имеющим значение, эквивалентное 1.0, отключает режим forwards-compatible для себя, своих атрибутов, своих потомков и их атрибутов.

Если элемент обрабатывается в режиме forwards-compatible, тогда:

Таким образом, любой процессор 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>

Если выражение появляется в атрибуте, обрабатываемом в режиме forwards-compatible, тогда процессор XSLT обязан страховать от ошибок так:

2.6 Комбинирование Таблиц Стилей

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

2.6.1 Подключение Таблицы Стилей

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

Таблица стилей XSLT может подключать другую таблицу стилей XSLT, используя элемент xsl:include. Элемент 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 подключает таблицу , и таблица 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 />

Таблица стилей XSLT может импортировать другую таблицу стилей XSLT, используя элемент xsl:import. Импортирование таблицы стилей - это то же, что её подключение (см. [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 в дереве импорта определён как имеющий более низкий import precedence/приоритет импорта, чем другой элемент xsl:stylesheet в дереве импорта, если он (1) будет посещён до посещения второго элемента xsl:stylesheet в послеупорядоченном пересечении/post-order traversal дерева импорта (т.е. пересечения дерева импорта, в котором элемент xsl:stylesheet посещается после его импортированных потомков). Каждое определение и правило шаблона имеет приоритет импорта, определяемый элементом xsl:stylesheet, содержащим его.

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

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

ПРИМЕЧАНИЕ: поскольку элементы xsl:import должны появляться до любых определений или шаблонных правил, реализация, обрабатывающая импортированные таблицы стилей от точки, в которой она обнаруживает элемент xsl:import, будет вычислять определения и шаблонные правила в возрастающем порядке приоритета импорта.

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

Является ошибкой, если таблица стилей явно или косвенно импортирует сама себя. Помимо этого, случай, когда таблица стилей с определённым URI импортируется в несколько мест, специально не обрабатывается. Import  tree/дерево импорта будет содержать отдельный элемент xsl:stylesheet для каждого места, куда таблица импортируется.

ПРИМЕЧАНИЕ: Если используется xsl:apply-imports (см. [5.6 Переопределение Шаблонных Правил]), поведение может отличаться от поведения, когда таблица стилей была импортирована только в место с наивысшим приоритетом импорта.

2.7 Внедрение Таблиц Стилей

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

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

ПРИМЕЧАНИЕ: чтобы использовать такой атрибут с функцией XPath id, он обязан быть объявлен явно в ОТД(Определении Типа Данных)/DTD как ID.

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

<?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">
  <!-- ignore -->
</xsl:template>
</xsl:stylesheet>
</head>
<body>
<para id="foo">
...
</para>
</body>
</doc>
ПРИМЕЧАНИЕ: таблица, внедрённая в документ, к которому она применяется, или которая может быть подключена или импортирована в таблицу стилей, которая внедрена таким образом, должна обычно содержать шаблонное правило, которое специфицирует, штаа элементы xsl:stylesheet игнорируются.

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

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

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

3.1 Дочерние Элементы Корневого Узла

Нормальные ограничения для дочерних элементов корневого узла для результирующего дерева смягчаются. Результирующее дерево может содержать любую последовательность узлов в качестве дочерних элементов, возможных для узла элемента. Точнее, оно может иметь дочерние текстовые узлы и любое количество дочерних узлов элемента. При записи с использованием метода вывода XML (см. [16 Вывод]), возможно, что результирующее дерево не окажется правильно сформированным/well-formed документом XML; однако оно всегда будет правильно сформированным внешним общим разбираемым экземпляром.

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

3.2 Base URI/Базовый URI

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

3.3 Unparsed Entities/Неразбираемые Экземпляры

Корневой узел имеет отображение, дающее URI каждому неразбираемому экземпляру, объявленному в ОТД документа. Этот URI генерируется из системного идентификатора и публичного идентификатора, специфицированных в объявлении экземпляра. Процессор XSLT может использовать публичный идентификатор для генерации URI экземпляра вместо URI, специфицированного в системном идентификаторе. Если процессор XSLT не использует публичный/public идентификатор для генерации URI, он обязан использовать системный идентификатор; если системный идентификатор является относительным URI, он обязан быть развёрнут в абсолютный URI с использованием URI ресурса, содержащего объявление экземпляра, в качестве базового URI [RFC2396].

3.4 Вырезание Пробелов

После того как дерево таблицы стилей или документа-источника сконструировано, но до того, как оно будет обработано XSLT, некоторые текстовые узлы демонтируются. Текстовый узел никогда не демонтируется, если только он не содержит только пробельные символы. Демонтаж текстового узла удаляет этот текстовый узел из дерева. Процесс демонтажа принимает на входе набор имён элементов, для которых пустое пространство должно быть сохранено. Процесс демонтажа применяется к таблицам стилей и к документам-источникам, но набор имён элементов, сохраняющих пустое пространство/whitespace-preserving elements, определяется иначе, чем для таблиц стилей и документов-источников.

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

Иначе текстовый узел демонтируется.

Атрибуты 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, если, и только если, NameTest будет true для элемента как XPath node test. Конфликты между элементами, совпадающими с xsl:strip-space и xsl:preserve-space, разрешаются тем же путём, что и конфликты между шаблонными правилами (см. [5.5 Разрешение Конфликтов Шаблонных Правил]). Таким образом, совпадение, применяемое к имени определённого элемента, определяется так:

Является ошибкой, если останется более одного совпадения. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан выполнить исправление путём выбора совпадения, из оставшихся, которое появилось последним в таблице стилей.

4 Выражения

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

Выражение обязано совпадать с продукцией Expr в XPath.

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

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

5 Шаблонные Правила

5.1 Модель Процессинга

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

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

5.2 Патэрны

Шаблонные правила идентифицируют узлы, к которым они применяются, с помощью pattern/патэрна. Патэрны также используются для нумерации (см. [7.7 Нумерация]) и для объявления ключей (см. [12.2 Ключи]). Патэрн специфицирует набор условий узла. Узел, удовлетворяющий условиям, совпадает с патэрном; узел, не удовлетворяющий условиям, не совпадает с патэрном. Синтаксис патэрна это поднабор синтаксиса выражений. В частности, пути размещения/location paths, удовлетворяющие определённым ограничениям, могут использоваться в качестве патэрна. Выражение, являющееся также патэрном, всегда вычисляется до объекта типа node-set/набор-узлов. Узел совпадает с патэрном, если этот узел является членом результата вычисления патэрна как выражения относительно некоторого возможного контекста; возможный контекст это тот, чей узел контекста совпадает с одним из его предков.

Вот несколько примеров патэрнов:

Патэрн обязан соответствовать грамматике Pattern. Pattern это набор патэрнов путей размещения, разделённых знаком |. Патэрн пути размещения/location path pattern это путь размещения, все шаги которого используют только оси child или attribute.
Хотя патэрны не обязаны использовать ось descendant-or-self, они могут использовать оператор // и оператор /. Патэрны пути размещения могут также начинаться вызовом   id или key с литеральным аргументом. Предикаты в патэрне могут использовать произвольные выражения, подобно предикатам/predicates в пути размещения (пути локализации).

Патэрны
[1]    Pattern    ::=    LocationPathPattern
| Pattern '|' LocationPathPattern
[2]    LocationPathPattern    ::=    '/' RelativePathPattern?
| IdKeyPattern (('/' | '//') RelativePathPattern)?
| '//'? RelativePathPattern
[3]    IdKeyPattern    ::=    'id' '(' Literal ')'
| 'key' '(' Literal ',' Literal ')'
[4]    RelativePathPattern    ::=    StepPattern
| RelativePathPattern '/' StepPattern
| RelativePathPattern '//' StepPattern
[5]    StepPattern    ::=    ChildOrAttributeAxisSpecifier NodeTest Predicate*
[6]    ChildOrAttributeAxisSpecifier    ::=    AbbreviatedAxisSpecifier
| ('child' | 'attribute') '::'

Патэрн определён как совпадающий с узлом, если, и только если, имеется возможный контекст, такой, что, когда патэрн вычисляется как выражение с данным контекстом, узел является членом результирующего набора узлов/node-set. Если узел совпадает, возможные контексты содержат узел контекста, являющийся узлом, совпадающим с любым предком данного узла, и списком контекстного узла, содержащим только контекстный узел.

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

ПРИМЕЧАНИЕ: он совпадает даже с элементом p, являющимся элементом документа, поскольку корень документа является родителем элемента документа.

Хотя семантика патэрнов специфицирована неявно в терминах вычисления выражения, можно легко понять значение патэрна без представления терминологии вычисления выражения. В патэрне | разделяет альтернативы; патэрн с одним или более знаком  | , разделяющим альтернативы, совпадает, если совпадает одна или более альтернатив. Патэрн, состоящий из последовательности StepPattern'ов, разделённых знаком / или //, совпадает справа налево. Патэрн совпадает только тогда, когда совпадает самый правый StepPattern и подходящий элемент совпадает с остатком патэрна; если имеется сепаратор / , тогда единственным подходящим элементом является родитель; если имеется сепаратор //, тогда подходящим элементом является любой предок. StepPattern, использующий ось дочернего, совпадает, если NodeTest является true для узла и узел не является узлом атрибута. StepPattern, использующий ось атрибута, совпадает, если NodeTest является true для узла и узел является узлом атрибута. Если имеются [] , тогда первое PredicateExpr в StepPattern вычисляется с узлом, совпадающим как контекстный узел, а родственники контекстного узла совпадают с NodeTest как список контекстного узла, если только совпадающий узел не является узлом атрибута, - тогда списком контекстного узла являются все атрибуты, имеющие того же предка, что и совпадающий атрибут, и (атрибуты) совпадающие с NameTest.

Например,

appendix//ulist/item[position()=1]

совпадает с узлом, если, и только если, всё нижеследующее верно/true:

5.3 Определение Шаблонных Правил

<!-- Category: top-level-element -->
<xsl:template
  match =pattern
  name = qname
  priority = number
  mode = qname>
  <!-- Content: (xsl:param*, template) -->
</xsl:template>

Шаблонное правило специфицируется элементом xsl:template. Атрибут match это Pattern, который идентифицирует узел(узлы)-источник, к которому правило применяется. Атрибут match необходим, если только элемент xsl:template не имеет атрибут name (см. [6 Именованные Шаблоны]). Значение атрибута match будет ошибочным, если содержит VariableReference. Содержимое элемента xsl:template это шаблон, который инициализируется при применении шаблонного правила.

Например, документ XML может содержать:

This is an <emph>important</emph> point.

Следующее шаблонное правило совпадает с элементами emph и производит объект форматирования (ОФ) fo:inline-sequence со свойством font-weight, имеющим значение bold.

<xsl:template match="emph">
  <fo:inline-sequence font-weight="bold">
    <xsl:apply-templates/>
  </fo:inline-sequence>
</xsl:template>
ПРИМЕЧАНИЕ: примеры в этом документе используют префикс fo: пространства имён http://www.w3.org/1999/XSL/Format, которое является пространством имён объектов форматирования, определённым в [XSL].

Как описано далее, элемент xsl:apply-templates рекурсивно обрабатывает потомков элемента-источника.

5.4 Применение Шаблонных Правил

<!-- Category: instruction -->
<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

Этот пример создаёт блок для элемента chapter и обрабатывает его непосредственных потомков.

<xsl:template match="chapter">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

При отсутствии атрибута select, инструкция xsl:apply-templates обрабатывает всех потомков текущего узла, включая текстовые узлы. Однако демонтированные текстовые узлы, как специфицировано в разделе [3.4 Вырезание Пробелов], не будут обрабатываться. Если демонтаж узлов пустого пространства для элемента не включён, тогда всё пустое пространство/пробелы в содержимом элемента обрабатывается как текст, и, таким образом, пустое пространство межу дочерними элементами будет высчитываться путём определения позиции дочернего элемента как возвращаемого функцией position.

Атрибут select может использоваться для обработки узлов, выбранных выражением, вместо обработки всех потомков. Значением атрибута select является выражение. Выражение обязано вычисляться до получения набора узлов/node-set. Выбранный набор узлов обрабатывается по порядку документов, если только не имеется спецификация сортировки (см. [10 Сортировка]).
В следующем примере обрабатываются все author - потомки author-group:

<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author"/>
  </fo:inline-sequence>
</xsl:template>

В следующем примере обрабатываются все given-name из author'ов - потомки author-group:

<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author/given-name"/>
  </fo:inline-sequence>
</xsl:template>

В этом примере обрабатываются все элементы heading - потомки элемента book

<xsl:template match="book">
  <fo:block>
    <xsl:apply-templates select=".//heading"/>
  </fo:block>
</xsl:template>

Можно также обрабатывать элементы, не являющиеся потомками текущего узла. В данном примере принимается, что элемент department имеет дочерние элементы group потомков employee. Находится департамент сотрудников и обрабатываются дочерние group из department.

<xsl:template match="employee">
  <fo:block>
    Employee <xsl:apply-templates select="name"/> belongs to group
    <xsl:apply-templates select="ancestor::department/group"/>
  </fo:block>
</xsl:template>

Несколько элементов xsl:apply-templates могут использоваться внутри одного шаблона для выполнения простого переупорядочивания. Следующий пример создаёт две таблицы HTML. Первая заполняется domestic sales, а вторая - foreign sales.

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic"/>
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign"/>
  </table>
</xsl:template>
ПРИМЕЧАНИЕ: здесь могут быть два совпадающих потомка, где один является потомком другого. Этот случай специально не рассматривается: оба потомка будут обрабатываться, как обычно. Например, данный документ-источник
<doc><div><div></div></div></doc>
и правило
<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>
оба будут обрабатывать элементы - внешний div и внутренний div.
ПРИМЕЧАНИЕ: обычно xsl:apply-templates используется для обработки только тех узлов, которые являются потомками текущего узла. Такое использование xsl:apply-templates не может дать в результате бесконечные циклы обработки. Однако, если xsl:apply-templates используется для обработки элементов, которые не являются потомками текущего узла, возрастает вероятность появления бесконечных циклов. Например,
<xsl:template match="foo">
  <xsl:apply-templates select="."/>
</xsl:template>
Реализации могут распознавать такие циклы в некоторых случаях, но существует вероятность, что таблица стилей может ввести бесконечный цикл, который не будет распознан реализацией. Это может вызвать запрет доступа из-за риска нарушения безопасности службы.

5.5 Разрешение Конфликтов Шаблонных Правил

Узел-источник может совпадать с более чем одним шаблонным правилом. Используемое шаблонное правило определяется тогда так:

  1. Сначала все совпадающие шаблонные правила, имеющие более низкий приоритет импорта, исключаются из рассмотрения.

  2. Затем все совпадающие шаблонные правила, имеющие более низкий приоритет, чем шаблонное правило или правила с самым высоки приоритетом, исключаются из рассмотрения. Приоритет шаблонного правила специфицируется атрибутом priority в этом шаблонном правиле. Значение его должно быть реальным числом (положительным или отрицательным), совпадающим с продукцией Number с необязательным ведущим знаком минус (-). Приоритет по умолчанию вычисляется так:

    Таким образом, самый обычный патэрн (тестирующий узел определённым типом и определённым развёрнутым именем/expanded-name) имеет приоритет 0. Следующий менее специфичный вид патэрна (тестирующий узел определённым типом и определённым развёрнутым именем с определённым URI пространства имён) имеет приоритет -0.25. Патэрны, менее специфичные, чем этот (патэрны, просто тестирующие данный узел определёнными типами), имеют приоритет -0.5. Патэрны, более специфичные, чем патэрны самых общих видов, имеют приоритет 0.5.

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

5.6 Переопределение Шаблонных Правил

<!-- Category: instruction -->
<xsl:apply-imports />

Шаблонное правило, которое используется для переопределения шаблонного правила в импортированной таблице стилей (см. [5.5 Разрешение Конфликтов Шаблонных Правил]), может использовать элемент xsl:apply-imports для вызова переопределённого шаблонного правила.

В любой точке процесса обработки таблицы стилей имеется текущее шаблонное правило. Где бы шаблонное правило ни было выбрано совпадением с патэрном, оно становится текущим шаблонным правилом для установки/инстанциации шаблона правила. Если элемент xsl:for-each инстанциирован, текущее шаблонное правило становится null для инстанциации содержимого элемента xsl:for-each.

xsl:apply-imports обрабатывает текущий узел, используя только те шаблонные правила, которые были импортированы в элемент таблицы стилей, содержащий текущее шаблонное правило; узел обрабатывается в режиме текущего шаблонного правила. Будет ошибкой, если xsl:apply-imports инстанциируется, когда текущее шаблонное правили - null.

Например, предположим, что таблица стилей doc.xsl содержит шаблонное правило для элементов example:

<xsl:template match="example">
  <pre><xsl:apply-templates/></pre>
</xsl:template>

Другая таблица стилей может импортировать doc.xsl и модифицировать обработку элементов example таким образом:

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

<xsl:template match="example">
  <div style="border: solid red">
     <xsl:apply-imports/>
  </div>
</xsl:template>

Комбинированный эффект для трансформации example в элемент формы:

<div style="border: solid red"><pre>...</pre></div>

5.7 Режимы/Modes

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

И xsl:template, и xsl:apply-templates имеют необязательный атрибут mode. Значением атрибута mode является QName, развёртываемое, как описано в разделе [2.4 Квалифицированные Имена]. Если xsl:template не имеет атрибута match, он обязан не иметь и атрибут mode. Если элемент xsl:apply-templates не имеет атрибута mode, тогда он применяется только к тем шаблонным правилам из элементов xsl:template, которые имеют атрибут mode с тем же значением; если элемент xsl:apply-templates не имеет атрибута mode, только к тем шаблонным правилам из элементов xsl:template, которые не имеют атрибута mode.

5.8 Встроенные Шаблонные Правила

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

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

Имеется также встроенное шаблонное правило для каждого режима, позволяющее продолжать рекурсивную обработку в том же режиме при отсутствии успешного совпадения патэрна посредством явно установленного в таблице стилей шаблонного правила. Это шаблонное правило применяется и к узлу элементов, и к корневому узлу. Далее показан эквивалент встроенного шаблонного правила для режима m.

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

Имеется также встроенное шаблонное правило для узлов текста и атрибутов, которое копирует текст:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

Встроенное шаблонное правило для инструкций процессинга и комментариев не выполняет никаких действий.

<xsl:template match="processing-instruction()|comment()"/>

Встроенное шаблонное правило для узлов пространства имён также не выполняет никаких действий. Отсутствует какой-либо патэрн, который может совпадать с узлом пространства имён; следовательно, встроенное шаблонное правило является единственным шаблонным правилом, применимым к узлу пространства имён.

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

6 Именованные Шаблоны

<!-- Category: instruction -->
<xsl:call-template
  name = qname>
  <!-- Content: xsl:with-param* -->
</xsl:call-template>

Шаблоны могут вызываться по имени. Элемент xsl:template с атрибутом name специфицирует именованный шаблон. Значением атрибута  name является QName, которое расширяется, как описано в разделе [2.4 Квалифицированные Имена]. Если элемент xsl:template имеет атрибут name, он может, но не обязан, иметь также и атрибут match. Элемент xsl:call-template вызывает шаблон по имени; он имеет обязательный атрибут name, идентифицирующий вызываемый шаблон. В отличие от xsl:apply-templates, xsl:call-template не изменяет текущий узел списка текущего узла.

Атрибуты match, mode и priority элемента xsl:template не влияют на то, вызывается ли шаблон элементом xsl:call-template. Аналогично и атрибут name элемента xsl:template не влияет на то, вызывается ли шаблон элементом xsl:apply-templates.

Является ошибкой, если таблица стилей содержит более одного шаблона с одним именем и тем же приоритетом импорта.

7 Создание Результирующего Дерева

В этом разделе описываются инструкции, непосредственно создающие узлы в результирующем дереве.

7.1 Создание Элементов и Атрибутов

7.1.1 Литеральные Результирующие Элементы

В шаблоне элемент таблицы стилей, не принадлежащий к пространству имён XSLT и не являющийся элементом расширения (см. [14.1 Элементы Расширения]), устанавливается для создания узла элементов с тем же расширяемым именем/expanded-name. Содержимое такого элемента является шаблоном, который устанавливается для придания содержимого создаваемому узлу элементов. Создаваемый узел элементов будет иметь узлы атрибутов, которые были представлены в узле элементов в дереве таблицы стилей, отличающиеся от атрибутов с именами пространства имён XSLT.

Создаваемый узел элементов будет также иметь копию узлов пространства имён, которые были представлены в узле элементов в дереве таблицы стилей, за исключением любых узлов пространства имён, чьим строковым значением является URI пространства имён XSLT (http://www.w3.org/1999/XSL/Transform), URI пространства имён, объявленного как пространство имён расширения (см. [14.1 Элементы Расширения]), или URI пространства имён, обозначенного как исключённое/excluded пространство имён. В URI пространства имён, обозначенного как исключённое, используется атрибут exclude-result-prefixes в элементе xsl:stylesheet или атрибут xsl:exclude-result-prefixes в литеральном результирующем элементе. Значением обоих этих атрибутов является список разделённых пробелами префиксов пространства имён. Пространство имён, привязанное к каждому из этих префиксов, назначается как исключённое пространство имён. Является ошибкой, если отсутствует пространство имён, связанное с префиксом элемента, порождающего атрибут exclude-result-prefixes или xsl:exclude-result-prefixes. Пространство имён по умолчанию (как объявлено в xmlns) может быть обозначено как исключённое пространство имён, путём включения #default в список префиксов пространства имён. Назначение пространства имён как исключённого эффективно в поддереве таблицы стилей, берущем начало в элементе, порождающем атрибуты exclude-result-prefixes или xsl:exclude-result-prefixes; поддерево, имеющее начало/rooted в элементе xsl:stylesheet, не включает никаких таблиц стилей, импортированных или включённых дочерними элементами этого элемента xsl:stylesheet.

ПРИМЕЧАНИЕ: если таблица стилей использует объявление пространства имён только для адресации дерева-источника, специфицирование префикса в атрибуте exclude-result-prefixes исключит излишние объявления пространства имён в результирующем дереве.

Значение атрибута литерального результирующего элемента интерпретируется как шаблон значения атрибута: оно может содержать выражения в фигурных скобках ({}).

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

<!-- Category: top-level-element -->
<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />

Таблица стилей может использовать элемент xsl:namespace-alias для объявления, что URI пространства имён является alias/псевдонимом для другого URI пространства имён. Если URI литерального пространства имён объявлен как псевдоним для другого URI пространства имён, тогда URI пространства имён в результирующем дереве будет URI пространства имён, этим URI литерального пространства имён, псевдонимом которого он является, вместо самого URI литерального пространства имён. Элемент xsl:namespace-alias объявляет, что URI пространства имён, связанный с префиксом, специфицированным атрибутом stylesheet-prefix, является псевдонимом для URI пространства имён, связанного с префиксом, специфицированным атрибутом result-prefix. Таким образом, атрибут stylesheet-prefix специфицирует URI пространства имён, который будет появляться в таблице стилей, а атрибут result-prefix специфицирует соответствующий URI пространства имён, который будет появляться в результирующем дереве. Пространство имён по умолчанию (как объявлено в xmlns) может быть специфицировано #default вместо префикса. Если URI пространства имён объявлен как псевдоним нескольких различных URI пространств имён, тогда используется объявление с наивысшим приоритетом импорта. Является ошибкой, если имеется более одного такого объявления. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию путём выбора из объявлений с наивысшим приоритетом импорта объявления, которое появилось последним в таблице стилей.

Если литеральные результирующие элементы используются для создания узлов элементов, атрибутов или пространства имён, которые используют URI пространства имён XSLT, таблица стилей обязана использовать псевдонимы. Например, таблица стилей

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

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

<xsl:template match="/">
  <axsl:stylesheet>
    <xsl:apply-templates/>
  </axsl:stylesheet>
</xsl:template>

<xsl:template match="block">
  <axsl:template match="{.}">
     <fo:block><axsl:apply-templates/></fo:block>
  </axsl:template>
</xsl:template>

</xsl:stylesheet>

будет генерировать таблицу стилей XSLT из документа в форме:

<elements>
<block>p</block>
<block>h1</block>
<block>h2</block>
<block>h3</block>
<block>h4</block>
</elements>
ПРИМЕЧАНИЕ: использование псевдонимов может понадобиться также для пространств имён, отличных от URI пространства имён XSLT. Например, литеральные результирующие элементы, принадлежащие к пространству имён, работающему с цифровыми подписями, могут вызвать неправильную обработку таблиц стилей XSLT программами, обеспечивающими безопасность; использование псевдонима для пространства имён исключает возможность такой неправильной обработки.

7.1.2 Создание Элементов с Помощью  xsl:element

<!-- Category: instruction -->
<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:element>

Элемент xsl:element позволяет создавать элемент с вычисляемым/computed именем. expanded-name создаваемого элемента специфицируется обязательным атрибутом name и необязательным атрибутом namespace. Содержимым элемента xsl:element является шаблон для атрибутов и потомков созданного элемента.

Атрибут name интерпретируется как шаблон значения атрибута. Является ошибкой, если строка, результирующая из установки шаблона значения атрибута, не является QName. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, делая результат установки элемента xsl:element последовательностью узлов, создаваемой установкой содержимого элемента xsl:element, исключая любые начальные узлы атрибутов. Если атрибут namespace не существует, тогда QName расширяется в expanded-name путём использования объявлений действующих пространств имён для элемента xsl:element, включая любое объявление пространства имён по умолчанию.

Если атрибут namespace существует, тогда он также интерпретируется как шаблон значения атрибута. Строка - результат установки шаблона значения атрибута должна быть URI-ссылкой. Считается ошибкой, если строка не является синтаксически верной URI-ссылкой. Если строка является пустой, тогда expanded-name элемента имеет нулевой/null URI пространства имён. Иначе строка используется как URI пространства имён расширенного имени/expanded-name создаваемого элемента. Локальная часть QName, специфицированная атрибутом name, используется как локальная часть expanded-name создаваемого элемента.

Процессоры XSLT могут использовать префикс для QName, специфицированного в атрибуте name, при выборе префикса, используемого для вывода созданного элемента как XML; однако они не обязаны делать это.

7.1.3 Создание Атрибутов с Помощью  xsl:attribute

<!-- Category: instruction -->
<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  <!-- Content: template -->
</xsl:attribute>

Элемент xsl:attribute может использоваться для добавления атрибутов к результирующим элементам, созданным литеральными результирующими элементами в таблице стилей или инструкциями, такими как xsl:element. expanded-name создаваемого атрибута специфицируется обязательным атрибутом name и необязательным атрибутом namespace. Установка элемента xsl:attribute добавляет узел атрибута к содержащему его результирующему узлу элемента. Содержимое элемента xsl:attribute - это шаблон значения созданного атрибута.

Атрибут name интерпретируется как шаблон значения атрибута. Является ошибкой, если строка, результирующая из установки шаблона значения атрибута, не является QName или является строкой xmlns. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, не добавляя атрибут в результирующее дерево. Если атрибут namespace не существует, тогда QName расширяется в expanded-name путём использования объявлений действующих пространств имён для элемента xsl:attribute, не включая любое объявление пространства имён по умолчанию.

Если атрибут namespace существует, тогда он также интерпретируется как шаблон значения атрибута. Строка, являющаяся результатом его установки должна быть URI-ссылкой. Не считается ошибкой, если строка не является синтаксически верной URI-ссылкой. Если строка является пустой, тогда expanded-name элемента имеет нулевой/null URI пространства имён. Иначе строка используется как URI пространства имён расширенного имени/expanded-name создаваемого атрибута. Локальная часть QName, специфицированная атрибутом name, используется как локальная часть expanded-name создаваемого атрибута.

Процессоры XSLT могут использовать префикс для QName, специфицированного в атрибуте name, при выборе префикса, используемого для вывода созданного элемента как XML; однако они не обязаны делать это, и, если есть префикс xmlns, они обязаны не делать этого. Таким образом, хотя и не будет ошибкой:

<xsl:attribute name="xmlns:xsl" namespace="whatever">http://www.w3.org/1999/XSL/Transform</xsl:attribute>

это в результате не даст на выходе объявление пространства имён.

Добавление атрибута к элементу замещает любой существующий атрибут данного элемента с тем же самым expanded-name.

Всё нижеследующее является ошибочным:

ПРИМЕЧАНИЕ: Когда xsl:attribute содержит текстовый узел с символом новой строки, вывод XML обязан содержать мнемонику символа. Например,
<xsl:attribute name="a">x
y</xsl:attribute>
даст в результате
a="x&#xA;y"
(или с любой эквивалентной мнемоникой символа). Вывод XML не может быть
a="x
y"
поскольку XML 1.0 требует нормализации символов новой строки в значениях атрибутов до пробелов, но требует не нормализовать мнемоники символов новой строки. Значения атрибутов в модели данных представляют значение атрибута после нормализации. Если новая строка, появляющаяся в значении атрибута в дереве, была выведена как символ новой строки, а не как мнемоника, то значение атрибута в дереве, создаваемом при повторном разборе XML, будет содержать пробел, а не новую строку, что может означать, что это дерево не было выведено корректно.

7.1.4 Именованные Наборы Атрибутов

<!-- Category: top-level-element -->
<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  <!-- Content: xsl:attribute* -->
</xsl:attribute-set>

Элемент xsl:attribute-set именованный набор атрибутов. Атрибут name специфицирует имя набора атрибутов. Значением атрибута name является QName, которое расширяется, как описано в разделе [2.4 Квалифицированные Имена]. Содержимое элемента xsl:attribute-set состоит из нуль или более элементов xsl:attribute, специфицирующих атрибуты в наборе.

Наборы атрибутов используются путём спецификации атрибута use-attribute-sets в элементах xsl:element, xsl:copy (см. [7.5 Копирование]) или xsl:attribute-set. Значением атрибута use-attribute-sets является список разделённых пробелами имён наборов атрибутов. Каждое имя специфицируется как QName, которое расширяется, как описано в разделе [2.4 Квалифицированные Имена]. Специфицирование атрибута use-attribute-sets эквивалентно добавлению элементов xsl:attribute для каждого атрибута в каждом именованном наборе атрибутов, начиная содержимое элемента атрибутом use-attribute-sets, в том же порядке, в котором имена наборов атрибутов специфицированы в атрибуте use-attribute-sets. Является ошибкой, если использование атрибутов use-attribute-sets в элементах xsl:attribute-set вызывает прямое или косвенное использование набором атрибутов самого себя.

Наборы атрибутов могут использоваться также при специфицировании атрибута xsl:use-attribute-sets в литеральном результирующем элементе. Значением атрибута xsl:use-attribute-sets является список разделённых пробелами имён наборов атрибутов. Атрибут xsl:use-attribute-sets действует так же, как и атрибут use-attribute-sets в xsl:element с дополнительным правилом: атрибуты, специфицированные в самом литеральном результирующем элементе, рассматриваются так, как будто они специфицированы элементами xsl:attribute до любого из действующих элементов xsl:attribute, но после любых элементов xsl:attribute, подразумеваемых атрибутом xsl:use-attribute-sets. Таким образом, для литерального результирующего элемента атрибуты из набора атрибутов, именованного в атрибуте xsl:use-attribute-sets, будут добавлены первыми в порядке, перечисленном в атрибуте; далее, будут добавлены атрибуты, специфицированные в литеральном результирующем элементе; наконец, будут добавлены любые атрибуты, специфицированные элементами xsl:attribute. Поскольку добавление атрибута элементу замещает любой имеющийся в этом элементе атрибут с тем же именем, это означает, что атрибуты, специфицированные набором атрибутов, могут быть переопределены атрибутами, специфицированными в самом результирующем элементе.

Шаблон внутри каждого элемента xsl:attribute в элементе xsl:attribute-set инстанциируется всякий раз, когда используется набор атрибутов; он инстанциируется, используя тот же текущий узел и тот же список текущего узла, которые используются для инстанциирования элемента, атрибут use-attribute-sets или xsl:use-attribute-sets. Однако в таблице стилей элемент xsl:attribute имеет позицию, в отличие от элементов, порождающих атрибут use-attribute-sets или xsl:use-attribute-sets, которая определяет, какие связи переменных/variable bindings видны (см. [11 Переменные и Параметры]); таким образом, только переменные и параметры, объявленные элементами top-level/верхнего уровня xsl:variable и xsl:param, являются видимыми.

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

<xsl:template match="chapter/heading">
  <fo:block quadding="start" xsl:use-attribute-sets="title-style">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:attribute-set name="title-style">
  <xsl:attribute name="font-size">12pt</xsl:attribute>
  <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

Несколько определений набора атрибутов с тем же расширенным именем/expanded-name объединяются. Атрибут из определения, имеющего более высокий приоритет импорта, имеет приоритет над атрибутом из определения, имеющего более низкий приоритет импорта. Считается ошибкой, если два набора атрибутов имеют одно expanded-name и одинаковый приоритет импорта и один и тот же атрибут при отсутствии определения набора атрибутов с более высоким приоритетом импорта, который (набор) также содержит этот атрибут. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, выбирая из нескольких определений, специфицирующих этот атрибут и имеющих наивысший приоритет, того атрибута, который был специфицирован последним в таблице стилей. Место, где специфицирован атрибут в наборе атрибутов, учитывается только в процессе слияния атрибутов в набор атрибутов; при использовании набора атрибутов никакого различия нет.

7.2 Создание Текста

Шаблон может также содержать текстовые узлы. Каждый текстовый узел в шаблоне, остающийся после демонтажа, как описано в разделе [3.4 Демонтаж Пустого Пространства], будет создавать в результирующем дереве текстовый узел с аналогичным строковым значением/string-value. Смежные текстовые узлы в результирующем дереве автоматически объединяются/сливаются.

Обратите внимание, что текст обрабатывается на уровне дерева. Таким образом, разметка &lt; в шаблоне будет представлена в дереве таблицы стилей текстовым узлом, включающим символ <. Это создаст в результирующем дереве текстовый узел, содержащий символ <, который будет представлен разметкой &lt; (или эквивалентной мнемоникой символа), когда результирующее дерево "экстернализируется"/воплощается как документ XML (если только escap'ирование не отключено, как описано в разделе [16.4 Отключение Escap'ирования Вывода]).

<!-- Category: instruction -->
<xsl:text
  disable-output-escaping = "yes" | "no">
  <!-- Content: #PCDATA -->
</xsl:text>

Литеральные символьные данные могут быть "упакованы" в элемент xsl:text. Такое "обёртывание" может изменить демонтируемое пустое пространство (см. [3.4 Демонтаж Пустого Пространства]), но не влияет на то, как символы обрабатываются впоследствии процессором XSLT.

ПРИМЕЧАНИЕ: Атрибуты xml:lang и xml:space не рассматриваются в XSLT особым образом. В частности,

7.3 Создание Инструкций Процессинга

<!-- Category: instruction -->
<xsl:processing-instruction
  name = { ncname }>
  <!-- Content: template -->
</xsl:processing-instruction>

Элемент xsl:processing-instruction инстанциируется для создания узла инструкции процессинга. Содержимым элемента xsl:processing-instruction является шаблон для string-value узла инструкции процессинга. Элемент xsl:processing-instruction имеет обязательный атрибут name, специфицирующий имя узла инструкции процессинга. Значение атрибута name интерпретируется как шаблон значения атрибута.

Например,

<xsl:processing-instruction name="xml-stylesheet">href="book.css" type="text/css"</xsl:processing-instruction>

может создать инструкцию процессинга/процесса

<?xml-stylesheet href="book.css" type="text/css"?>

Считается ошибкой, если строка, результирующая из инстанциации атрибута name, не является NCName или PITarget. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, не добавляя инструкцию процессинга к результирующему дереву.

ПРИМЕЧАНИЕ: Это означает, что xsl:processing-instruction не может использоваться для вывода объявления XML. Вместо этого должен использоваться элемент xsl:output (см. [16 Вывод]).

Считается ошибкой, если инстанциация содержимого xsl:processing-instruction создаёт нетекстовые узлы. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, игнорируя узлы-нарушители вместе с их содержимым.

Считается ошибкой, если инстанциация содержимого xsl:processing-instruction содержит строку  ?>. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, вставляя пробел после любого вхождения ? с последующей >.

7.4 Создание Комментариев

<!-- Category: instruction -->
<xsl:comment>
  <!-- Content: template -->
</xsl:comment>

Элемент xsl:comment инстанциируется для создания узла комментария в результирующем дереве. Содержимым элемента xsl:comment является шаблон для string-value узла комментария.

Например,

<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>

создаст комментарий

<!--This file is automatically generated. Do not edit!-->

Считается ошибкой, если инстанциация содержимого xsl:comment создаёт нетекстовые узлы. Процессор XSLT может сигнализировать об ошибке; если он этого не делает, он обязан обработать ситуацию, игнорируя узлы-нарушители вместе с их содержимым.

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

7.5 Копирование

<!-- Category: instruction -->
<xsl:copy
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:copy>

Элемент xsl:copy позволяет легко скопировать текущий узел. Инстанциация элемента xsl:copy создаёт копию текущего узла. Узлы пространств имён текущего узла также автоматически копируют, но атрибуты и потомки текущего узла не копируются автоматически. Содержимое элемента xsl:copy является шаблоном для атрибутов и потомков созданного узла; это содержимое инстанциируется только для таких типов узлов, которые могут иметь атрибуты или потомков (например, корневые узлы и узлы элементов).

Элемент xsl:copy может иметь атрибут use-attribute-sets (см. [7.1.4 Именованные Наборы Атрибутов]). Это используется только при копировании узлов элементов.

Корневой узел рассматривается особо, поскольку корневой узел/root node результирующего дерева создаётся неявным образом. Если текущим узлом является корневой узел, xsl:copy создаст корневой узел, но просто будет использовать шаблон содержимого.

Например, трансформация тождества может быть записана с использованием xsl:copy:

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

Когда текущий узел является атрибутом, то, если ошибкой будет использование xsl:attribute для создания атрибута с тем же именем, что у текущего узла, то ошибкой будет также использование xsl:copy (см. [7.1.3 Создание Атрибутов с  xsl:attribute]).

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

<xsl:template name="apply-templates-copy-lang">
 <xsl:for-each select="@xml:lang">
   <xsl:copy/>
 </xsl:for-each>
 <xsl:apply-templates/>
</xsl:template>

то можно легко выполнить

<xsl:call-template name="apply-templates-copy-lang"/>

вместо

<xsl:apply-templates/>

когда нужно скопировать атрибут xml:lang.

7.6 Обсчёт Сгенерированного Текста

С помощью шаблона элемент xsl:value-of можно использовать для обсчёта сгенерированного текста, например, извлечением текста из исходного дерева или вставкой значения переменной. Элемент xsl:value-of делает это с помощью expression/выражения, которое специфицируется как значение атрибута select. Выражения также могут использоваться в значениях атрибутов литеральных результирующих элементов путём заключения выражения в фигурные скобки ({}).

7.6.1 Генерация Текста с Помощью xsl:value-of

<!-- Category: instruction -->
<xsl:value-of
  select = string-expression
  disable-output-escaping = "yes" | "no" />

Элемент xsl:value-of инстанциируется для создания текстового узла в результирующем дереве. Необходимый атрибут select является expression/выражением; это выражение вычисляется и результирующий объект конвертируется в строку, как если бы это был вызов функции string. Строка специфицирует строковое значение/string-value создаваемого текстового узла. Если строка пуста, текстовый узел не будет создан. Создаваемый текстовый узел будет объединён с любыми смежными текстовыми узлами.

Элемент xsl:copy-of может использоваться для копирования набора узлов в результирующее дерево без конвертации его в строку. См. [11.3 Использование Значений Переменных и Параметров с  xsl:copy-of].

Например, вот создание HTML-параграфа из элемента person с атрибутами given-name и family-name. Этот параграф будет содержать значение атрибута given-name текущего узла с последующими пробелом и значением атрибута family-name текущего узла.

<xsl:template match="person">
  <p>
   <xsl:value-of select="@given-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="@family-name"/>
  </p>
</xsl:template>

В другом примере создаётся HTML-параграф из элемента person с дочерними элементами given-name и family-name. Этот параграф будет содержать строковое значение /string-value первого элемента-потомка given-name текущего узла с последующими пробелом и string-value первого элемента-потомка family-name текущего узла.

<xsl:template match="person">
  <p>
   <xsl:value-of select="given-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="family-name"/>
  </p>
</xsl:template>

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

<xsl:template match="procedure">
  <fo:block>
    <xsl:value-of select="ancestor-or-self::*[@security][1]/@security"/>
  </fo:block>
  <xsl:apply-templates/>
</xsl:template>

7.6.2 Шаблоны Значений Атрибутов

В значении атрибута, интерпретирующемся как шаблон значения атрибута, таком как атрибут литерального результирующего элемента, может использоваться выражение/expression, заключённое в фигурные скобки ({}). Шаблон значения атрибута инстанциируется путём замещения этого выражения/expression и фигурных скобок результатом вычисления этого выражения и конвертацией результирующего объекта в строку, как если бы вызывалась функция string. Фигурные скобки не распознаются в значении атрибутов в таблице стилей XSLT, если только атрибут специально не установлен как интерпретируемый в качестве шаблона значения атрибута; резюмируя синтаксис элемента, значение таких атрибутов заключается в фигурные скобки.

ПРИМЕЧАНИЕ: не все атрибуты интерпретируются как шаблоны значений атрибутов. Атрибуты, чьи значения являются патэрном или выражением, атрибуты элементов верхнего уровня/ top-level и атрибуты, ссылающиеся на именованные XSLT-объекты, не интерпретируются как шаблоны значений атрибутов. Кроме того, xmlns-атрибуты не интерпретируются как шаблоны значений атрибутов; это не соответствовало бы Рекомендациям XML Namespaces.

В следующем примере создаётся результирующий элемент img из исходного элемента photograph; значение атрибута src элемента img вычисляется значения переменной image-dir, и строкового значения href-потомка элемента photograph; значение атрибута width элемента img вычисляется из значения атрибута width потомка size элемента photograph:

<xsl:variable name="image-dir">/images</xsl:variable>

<xsl:template match="photograph">
<img src="{$image-dir}/{href}" width="{size/@width}"/>
</xsl:template>

С таким исходником

<photograph>
  <href>headquarters.jpg</href>
  <size width="300"/>
</photograph>

результат может быть таким:

<img src="/images/headquarters.jpg" width="300"/>

Когда шаблон значения атрибута инстанциирован, Двойная левая или правая фигурная скобка вне выражения замещается одинарной фигурной скобкой. Будет ошибкой, если правая фигурная скобка появится в шаблоне значения атрибута вне выражения без последующей правой фигурной скобки. Правая фигурная скобка внутри Literal/Литерала в выражении не распознаётся как терминатор выражения.

Фигурные скобки не распознаются рекурсивно внутри выражений. Например:

<a href="#{id({@ref})/title}">

не допускается. Вместо этого используйте простое:

<a href="#{id(@ref)/title}">

7.7 Нумерация

<!-- Category: instruction -->
<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

Элемент xsl:number используется для вставки форматированного числа в результирующее дерево. Вставляемое число может быть специфицировано выражением. Атрибут value содержит expression/выражение. Это выражение вычисляется, а результирующий объект конвертируется в число, как если бы была вызвана функция number. Это число округляется в целое/integer и конвертируется в строку с использованием специфицированных атрибутов [7.7.1 Атрибуты Конвертации Чисел в Строки]; в данном контексте значение каждого из этих атрибутов интерпретируется как шаблон значения атрибута. После конвертации результирующая строка вставляется в результирующее дерево. Например, в следующем примере нумеруется отсортированный список:

<xsl:template match="items">
  <xsl:for-each select="item">
    <xsl:sort select="."/>
    <p>
      <xsl:number value="position()" format="1. "/>
      <xsl:value-of select="."/>
    </p>
  </xsl:for-each>
</xsl:template>

Если атрибут value не специфицирован, то элемент xsl:number вставляет номера на основе позиции текущего узла в дереве-исходнике. Следующие атрибуты управляют нумерацией текущего узла:

Кроме того, специфицированные в разделе [7.7.1 Атрибуты Конвертации Чисел в Строки], используются для конвертации числа в строку, как в случае со специфицированным атрибутом value.

Элемент xsl:number сначала конструирует список положительных целых чисел с помощью атрибутов level, count и from:

Этот список чисел затем конвертируется в строку с использованием атрибутов, специфицированных в [7.7.1 Атрибуты Конвертации Чисел в Строки]; в данном контексте значение каждого этого атрибута интерпретируется как шаблон значения атрибута. После конвертации результирующая строка вставляется в результирующее дерево.

Следующий пример нумерует элементы как упорядоченный список:

<xsl:template match="ol/item">
  <fo:block>
    <xsl:number/><xsl:text>. </xsl:text><xsl:apply-templates/>
  </fo:block>
<xsl:template>

Следующие два правила нумеруют элементы title. это предназначено для документа, содержащего последовательность глав, затем - последовательность приложений, где и главы, и приложения содержат разделы, которые, в свою очередь, содержат подразделы. Главы нумеруются 1, 2, 3; приложения нумеруются A, B, C; разделы глав нумеруются 1.1, 1.2, 1.3; разделы приложений нумеруются A.1, A.2, A.3.

<xsl:template match="title">
  <fo:block>
     <xsl:number level="multiple"
                 count="chapter|section|subsection"
                 format="1.1 "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="appendix//title" priority="1">
  <fo:block>
     <xsl:number level="multiple"
                 count="appendix|section|subsection"
                 format="A.1 "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

В следующем примере примечания/notes нумеруются последовательно на протяжении главы:

<xsl:template match="note">
  <fo:block>
     <xsl:number level="any" from="chapter" format="(1) "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

В следующем примере нумеруются элементы H4 в HTML трёхчастными метками:

<xsl:template match="H4">
 <fo:block>
   <xsl:number level="any" from="H1" count="H2"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H2" count="H3"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H3" count="H4"/>
   <xsl:text> </xsl:text>
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

7.7.1 Атрибуты Конвертации Чисел в Строки

Следующие атрибуты применяются для управления конвертацией списка чисел в строку. Это целые числа/integer больше 0. Все эти атрибуты являются необязательными/optional.

Главным атрибутом является format. Значением по умолчанию атрибута format является 1. Атрибут format делится на последовательность лексем/tokens, где каждая лексема является максимальной последовательностью алфавитно-числовых символов или максимальной последовательностью неалфавитно-числовых символов. "Алфавитно-числовые" означает любой символ, имеющий категорию Unicode Nd, Nl, No, Lu, Ll, Lt, Lm или Lo. Алфавитно-числовые лексемы (лексемы формата) специфицируют формат, используемый для каждого числа списка. Если первая лексема является неалфавитно-числовой лексемой, то конструируемая строка начинается этой лексемой; если последняя лексема является неалфавитно-числовой лексемой, то конструируемая строка заканчивается этой лексемой. Неалфавитно-числовые лексемы, появляющиеся между двумя лексемами формата, являются лекскемами-сепараторами, которые используются для объединения чисел в список. n-ная лексема формата будет использована для форматирования n-ного числа списка. Если количество чисел больше количества лексем формата, то последняя лексема формата будет использована для форматирования оставшихся чисел. Если лексемы формата отсутствуют, то лексема формата 1 будет использована для форматирования всех чисел. Лексема формата специфицирует строку, используемую для представления числа 1. Каждое число после первого будет отделено от предшествующего числа лексемой-сепаратором, предшествующей лексеме формата, используемой для форматирования этого числа, или, если лексемы формата отсутствуют, символом . (точка).

Лексемы формата являются наднабором/superset допустимых значений атрибута type для элемента OL в  HTML 4.0 и интерпретируются так:

При нумеровании алфавитными символами атрибут lang специфицирует используемый алфавит символов; он имеет тот же диапазон значений, что и xml:lang [XML]; если не специфицировано никакого значения lang, язык должен определяться из системного окружения. Реализаторы должны документировать, нумерация каких языков поддерживается.

ПРИМЕЧАНИЕ: реализаторы не должны делать какие-либо предположения о работе нумерации в конкретных языках и должны детально исследовать, как нумерация работает в тех языках, которые предполагается использовать. Конвертация чисел во многих языках значительно отличается от конвертации в английском языке.

Атрибут letter-value устраняет неоднозначность между последовательностями нумерации с использованием букв. Во многих языках имеются две последовательности букв, используемых для нумерации. Одна последовательность использует числовые значения для нумерации букв в алфавитной последовательности, а другая присваивает числовые значения каждой букве в традиционной для данного языка манере. В английском языке это будет соответствовать последовательности чисел, специфицированной лексемами формата a и i. В некоторых языках первый член каждой последовательности - один и тот же, поэтому лексемы формата будут неоднозначны. Значение alphabetic специфицирует алфавитную последовательность; значение traditional специфицирует иную последовательность. Если атрибут letter-value не специфицирован, то от конкретной реализации будет зависеть, насколько точно разрешается неоднозначность нумерации.

ПРИМЕЧАНИЕ: допускается, что два разных соответствующих XSLT процессора не будут конвертировать число в совершенно одинаковые строки. Некоторые XSLT-процессоры могут не поддерживать отдельные языки. Кроме того, возможны варианты конвертации, выполняемой в конкретных языках, когда конвертация не специфицируется атрибутами в xsl:number. В следующих версиях XSLT могут появиться дополнительные атрибуты для управления этими вариантами. В реализациях можно использовать для этих целей также специфичные для данной реализации атрибуты пространства имён в xsl:number.

Атрибут grouping-separator предоставляет сепаратор/разделитель, используемый как группирующий сепаратор (например, для тысяч) в последовательностях десятеричных чисел, а необязательный grouping-size специфицирует размер (обычно 3) группы. Например, grouping-separator="," и grouping-size="3" дадут сила в форме 1,000,000. Если специфицирован только один атрибут: grouping-separator или grouping-size, то он игнорируется.

Вот примеры спецификации конвертации:

8 Повторение

<!-- Category: instruction -->
<xsl:for-each
  select = node-set-expression>
  <!-- Content: (xsl:sort*, template) -->
</xsl:for-each>

Если результат имеет известную стандартную структуру, то хорошо иметь возможность специфицировать шаблон непосредственно для выбранных узлов. Инструкция xsl:for-each содержит шаблон, который инстанциируется для каждого узла, выбранного выражением expression, специфицированным атрибутом select. Атрибут select необходим/required. Выражение обязано вычисляться в набор узлов/node-set. Шаблон инстанциируется с выбранным узлом как текущий узел/current node, а со списком всех выбранных узлов - как список текущих узлов/current node list. Узлы обрабатываются в порядке документа, если только нет особой спецификации сортировки (см. [10 Сортировка]).

Например, имея документ XML с такой структурой

<customers>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
</customers>

следующий код создаст HTML-документ, содержащий таблицу с рядом для каждого элемента customer

<xsl:template match="/">
  <html>
    <head>
      <title>Customers</title>
    </head>
    <body>
      <table>
	<tbody>
	  <xsl:for-each select="customers/customer">
	    <tr>
	      <th>
		<xsl:apply-templates select="name"/>
	      </th>
	      <xsl:for-each select="order">
		<td>
		  <xsl:apply-templates/>
		</td>
	      </xsl:for-each>
	    </tr>
	  </xsl:for-each>
	</tbody>
      </table>
    </body>
  </html>
</xsl:template>

9 Условный Процессинг

В XSLT имеются две инструкции, поддерживающие условный процессинг (обработку) в шаблоне: xsl:if и xsl:choose. Инструкция xsl:if работает как простой оператор if-then; инструкция xsl:choose поддерживает выбор одной опции при наличии нескольких.

9.1 Условный Процессинг с xsl:if

<!-- Category: instruction -->
<xsl:if
  test = boolean-expression>
  <!-- Content: template -->
</xsl:if>

Элемент xsl:if имеет атрибут test, который специфицирует выражение/expression. Содержимым является шаблон. Это выражение вычисляется и результирующий объект конвертируется в булево выражение, как если бы была вызвана функция boolean. Если результат true, то содержимое шаблона инстанциируется (создаётся экземпляр); иначе ничего не создаётся. В следующем примере имена в группе имён форматируются как список с разделением запятыми:

<xsl:template match="namelist/name">
  <xsl:apply-templates/>
  <xsl:if test="not(position()=last())">, </xsl:if>
</xsl:template>

Следующий код окрашивает каждый второй ряд таблицы в жёлтый цвет:

<xsl:template match="item">
  <tr>
    <xsl:if test="position() mod 2 = 0">
       <xsl:attribute name="bgcolor">yellow</xsl:attribute>
    </xsl:if>
    <xsl:apply-templates/>
  </tr>
</xsl:template>

9.2 Условный Процессинг с Помощью xsl:choose

<!-- Category: instruction -->
<xsl:choose>
  <!-- Content: (xsl:when+, xsl:otherwise?) -->
</xsl:choose>

<xsl:when
  test = boolean-expression>
  <!-- Content: template -->
</xsl:when>

<xsl:otherwise>
  <!-- Content: template -->
</xsl:otherwise>

Элемент xsl:choose выбирает один вариант из нескольких. Он состоит из последовательности элементов xsl:when с последующим необязательным элементом xsl:otherwise. Каждый элемент xsl:when имеет единственный атрибут, test, который специфицирует выражение/expression. Содержимое элементов xsl:when и xsl:otherwise является шаблоном. Когда обрабатывается элемент xsl:choose, каждый элемент xsl:when в свою очередь проверяется путём вычисления выражения и конвертации результирующего объекта в boolean, как если бы вызывалась функция boolean. Содержимое первого, и только первого элемента xsl:when, проверка которого даст true, инстанциируется. Если ни один из xsl:when не даст true, инстанциируется содержимое элемента xsl:otherwise. Если ни один из xsl:when не даст true и нет ни одного элемента xsl:otherwise, ничего не создаётся.

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

<xsl:template match="orderedlist/listitem">
  <fo:list-item indent-start='2pi'>
    <fo:list-item-label>
      <xsl:variable name="level"
                    select="count(ancestor::orderedlist) mod 3"/>
      <xsl:choose>
        <xsl:when test='$level=1'>
          <xsl:number format="i"/>
        </xsl:when>
        <xsl:when test='$level=2'>
          <xsl:number format="a"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:number format="1"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>. </xsl:text>
    </fo:list-item-label>
    <fo:list-item-body>
      <xsl:apply-templates/>
    </fo:list-item-body>
  </fo:list-item>
</xsl:template>

10 Сортировка

<xsl:sort
  select = string-expression
  lang = { nmtoken }
  data-type = { "text" | "number" | qname-but-not-ncname }
  order = { "ascending" | "descending" }
  case-order = { "upper-first" | "lower-first" } />

Сортировка специфицируется путём добавления элементов xsl:sort как дочерних элементов для элемента xsl:apply-templates или xsl:for-each. Первый дочерний xsl:sort специфицирует первичный ключ сортировки/primary sort key, второй дочерний xsl:sort специфицирует вторичный ключ сортировки, и так далее. Если элемент xsl:apply-templates или xsl:for-each имеет один или более дочерних xsl:sort, то, вместо процессинга выбранных узлов в порядке документа, он сортирует узлы в соответствии со специфицированными ключами сортировки, а затем обрабатывает их в отсортированном виде. При использовании в xsl:for-each элементы xsl:sort обязаны появляться первыми. Если шаблон инстанциируется с помощью xsl:apply-templates и xsl:for-each, current node list/список текущего узла состоит из полного списка узлов, обработанных в отсортированном порядке.

xsl:sort имеет атрибут select, значением которого является выражение. Для каждого обрабатываемого узла это выражение вычисляется с этим узлом как текущим узлом и с полным списком узлов, обрабатываемых в неотсортированном порядке как список текущего узла. Результирующий объект конвертируется в строку, как при вызове функции string; эта строка используется как ключ сортировки данного узла. Значением по умолчанию атрибута select является ., которое вызывает использование строкового значения текущего узла в качестве ключа сортировки.

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

ПРИМЕЧАНИЕ: допускается, что два соответствующих XSLT-процессора могут сортировать по разному. Некоторые XSLT-процессоры могут не поддерживать конкретные языки. Кроме того, возможны разные варианты сортировки в определённых языках, не специфицируемые атрибутами элемента xsl:sort, например, сортировка Hiragana или Katakana в японском. В последующих версиях XSLT могут появиться дополнительные атрибуты для управления такими вариантами. В реализациях могут также использоваться для этого специфические для данной реализации атрибуты пространства имён для элемента xsl:sort.
ПРИМЕЧАНИЕ: рекомендуется консультироваться с [UNICODE TR10] на предмет информации об интернационализированной сортировке.

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

Например, база данных employee имеет вид

<employees>
  <employee>
    <name>
      <given>James</given>
      <family>Clark</family>
    </name>
    ...
  </employee>
</employees>

Тогда список служащих/employees, отсортированный по алфавиту, может быть сгенерирован так:

<xsl:template match="employees">
  <ul>
    <xsl:apply-templates select="employee">
      <xsl:sort select="name/family"/>
      <xsl:sort select="name/given"/>
    </xsl:apply-templates>
  </ul>
</xsl:template>

<xsl:template match="employee">
  <li>
    <xsl:value-of select="name/given"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="name/family"/>
  </li>
</xsl:template>

11 Переменные и Параметры

<!-- Category: top-level-element -->
<!-- Category: instruction -->
<xsl:variable
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:variable>

<!-- Category: top-level-element -->
<xsl:param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:param>

Переменная это имя, которое можно связать со значением. Значение, с которым связана переменная (значение/value этой переменной) может быть объектом любого типа, который может быть возвращён выражениями. Есть два элемента, которые могут использоваться для связывания переменной со значением: xsl:variable и xsl:param. Разница между ними в том, что значение, специфицированное переменной xsl:param это только значение по умолчанию; когда вызывается шаблон или таблица стилей, внутри которых появился элемент xsl:param, можно передавать параметры, которые используются вместо значения по умолчанию.

И xsl:variable, и xsl:param имеют обязательный атрибут name, который специфицирует имя переменной. Значением атрибута name является QName, которое разворачивается, как указано в разделе [2.4 Квалифицированные Имена].

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

11.1 Фрагменты Результирующего Дерева

Переменные вводят дополнительный тип данных/data-type в язык выражений. Этот тип данных называется фрагмент результирующего дерева/result tree fragment. Переменная может быть связана с фрагментом результирующего дерева вместо одного из четырёх базовых типов данных XPath (string, number, boolean, node-set). Фрагмент результирующего дерева рассматривается эквивалентно node-set, содержащему только простой корневой узел. Однако операции, разрешённые во фрагменте результирующего дерева, являются поднабором операций, разрешённых в node-set. Операция разрешена только во фрагменте результирующего дерева, если она разрешена со string (операции со string могут потребовать сначала конвертации string в number или boolean). Конкретнее: не разрешается использовать операции /, // и [] во фрагментах результирующего дерева. Если разрешённая операция выполняется во фрагменте результирующего дерева, она выполняется точно так же, как выполнялась бы в эквивалентном node-set/наборе узлов.

Когда фрагмент результирующего дерева копируется в результирующее дерево (см. [11.3 Использование Значений Переменных и Параметров с xsl:copy-of]), то все узлы , являющиеся дочерними по отношению к корневому узлу в эквивалентном node-set, последовательно добавляются в результирующее дерево.

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

11.2 Значения Переменных и Параметров

Элемент, связывающий переменные, может специфицировать значение переменной тремя альтернативными способами:

ПРИМЕЧАНИЕ: когда переменная используется для выбора узлов по их позиции, будьте внимательны и не делайте так:
<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[$n]"/>
Это выведет значение первого элемента, поскольку переменная n будет связана с фрагментом результирующего дерева, а не с числом. Вместо этого сделайте так
<xsl:variable name="n" select="2"/>
...
<xsl:value-of select="item[$n]"/>
или
<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[position()=$n]"/>
ПРИМЕЧАНИЕ: удобным способом специфицировать пустой набор узлов/node-set в качестве значения по умолчанию параметра является:
<xsl:param name="x" select="/.."/>

11.3 Использование Значений Переменных и Параметров с xsl:copy-of

<!-- Category: instruction -->
<xsl:copy-of
  select = expression />

Элемент xsl:copy-of может использоваться для вставки фрагмента результирующего дерева в результирующее дерево без предварительной конвертации его в строку, как это делает xsl:value-of (см. [7.6.1 Генерирование Текста с Помощью  xsl:value-of]). Обязательный атрибут select содержит выражение. Если результатом вычисления выражения является фрагмент результирующего дерева, фрагмент полностью копируется в результирующее дерево. Если результатом является набор узлов, все узлы этого набора копируются, в порядке их расположения в документе, в результирующее дерево; копирование узла элементов копирует узлы атрибутов, узлы пространств имён и потомков узла элементов, а также сам узел элементов; корневой узел копируется при копировании его потомков. Если результатом является ни набор узлов, ни фрагмент результирующего дерева, результат конвертируется в строку/string, а затем вставляется в результирующее дерево, как при использовании xsl:value-of.

11.4 Переменные и Параметры Верхнего Уровня

Как xsl:variable, так и xsl:param разрешены как элементы top-level/верхнего уровня. Элемент верхнего уровня, связывающий переменные, объявляет глобальную переменную, которая видна в любой точке. Элемент верхнего уровня xsl:param объявляет параметр таблицы стилей; XSLT не определяет механизм передачи параметров в таблицу стилей. Ошибкой является, если таблица стилей/stylesheet содержит более одного связывания переменной верхнего уровня с одним и тем же именем и с тем же приоритетом импорта/import precedence. На верхнем уровне, выражение или шаблон, специфицирующие значение переменной, вычисляются с тем же контекстом, который используется для обработки корневого узла исходного документа: текущим узлом является корневой узел исходного документа, а списком текущего узла является список, содержащий только корневой узел исходного документа. Если шаблон или выражение, специфицирующие значение глобальной переменной x, ссылаются на глобальную переменную y, то значение y обязано вычисляться до вычисления значения x. Является ошибкой, если это невозможно сделать для определений всех глобальных переменных; другими словами - является ошибкой, если определения являются зацикленными.

В этом примере объявляется глобальная переменная para-font-size, на которую сделана ссылка в шаблоне значения атрибута:

<xsl:variable name="para-font-size">12pt</xsl:variable>

<xsl:template match="para">
 <fo:block font-size="{$para-font-size}">
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

11.5 Переменные и Параметры Внутри Шаблона

Так же, как и на верхнем уровне, xsl:variable и xsl:param разрешены также и в шаблонах. xsl:variable допускается в любом месте шаблона, где разрешена инструкция. В этом случае связывание видно во всех родственниках и их потомках. Обратите внимание, что это связывание невидимо для самого элемента xsl:variable. xsl:param допускается в качестве дочернего в начале элемента xsl:template. В данном контексте связывание видимо всем разрешённым родственникам и их потомкам. Обратите внимание, что это связывание невидимо для самого элемента xsl:param.

Связывание затеняет другое связывание, если первое появляется в точке, где второе видимо, а оба связывания имеют одинаковые имена. Является ошибкой, если связывание, установленное элементом xsl:variable или xsl:param в шаблоне, shadows/затеняет другое связывание, установленное элементом xsl:variable или xsl:param также в шаблоне. Не является ошибкой, если связывание, установленное элементом xsl:variable или xsl:param в шаблоне, затеняет другое связывание, установленное элементом xsl:variable или xsl:param верхнего уровня. Таким образом, следующее является ошибкой:

<xsl:template name="foo">
<xsl:param name="x" select="1"/>
<xsl:variable name="x" select="2"/>
</xsl:template>

Однако следующее разрешено:

<xsl:param name="x" select="1"/>
<xsl:template name="foo">
<xsl:variable name="x" select="2"/>
</xsl:template>
ПРИМЕЧАНИЕ: ближайшим эквивалентом в Java для элемента xsl:variable в шаблоне является объявление final local переменной инициализатором. Например,
<xsl:variable name="x" select="'value'"/>
имеет семантику, сходную с
final Object x = "value";
В XSLT нет эквивалента операции присвоения Java
x = "value";
поскольку это затруднит создание реализации, обрабатывающей документ иным способом, нежели пакетный, от начала до конца.

11.6 Передача Параметров в Шаблоны

<xsl:with-param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:with-param>

Параметры передаются в шаблоны с помощью элемента xsl:with-param. Обязательный атрибут name специфицирует имя параметра (переменную, которую замещает связанное с ней значение). Значением атрибута name является QName, которое разворачивается, как указано в разделе [2.4 Квалифицированные Имена]. xsl:with-param допускается в xsl:call-template и в xsl:apply-templates. Значение параметра специфицируется тем же способом, что для xsl:variable т xsl:param. Текущие узел и список узлов, используемые для обсчёта значения, специфицированного элементом xsl:with-param, - те же, что используются для элементов xsl:apply-templates или xsl:call-template, внутри которых появляются. Не является ошибкой передача параметра x в шаблон, не имеющий элемента xsl:param для x; этот параметр просто игнорируется.

В следующем примере определяется именованный шаблон для numbered-block с аргументом для управления форматом числа:

<xsl:template name="numbered-block">
  <xsl:param name="format">1. </xsl:param>
  <fo:block>
    <xsl:number format="{$format}"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="ol//ol/li">
  <xsl:call-template name="numbered-block">
    <xsl:with-param name="format">a. </xsl:with-param>
  </xsl:call-template>
</xsl:template>

12 Дополнительные Функции

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

12.1 Несколько Документов-Источников

Функция: node-set document(object, node-set?)

Функция document даёт доступ к XML-документам, отличным от основного документа-источника.

Если функция document имеет точно один аргумент и этим аргументом является node-set/набор узлов, то результатом будет union/объединение (для каждого аргумента в наборе узлов) результатов вызова функции document с первым аргументом, string-value (строковое значение) узла, и вторым аргументом, node-set с этим узлом в качестве его единственного члена. Если функция document имеет два аргумента и первый аргумент является набором узлов, то результатом будет union (для каждого узла в наборе узлов аргумента) результатов вызова функции document с первым аргументом - string-value узла - и вторым аргументом - вторым аргументом, переданным функции document.

Если первым аргументом функции document не является node-set, то первый аргумент конвертируется в строку, как если бы была вызвана функция string. Эта строка рассматривается как URI-ссылка; ресурс идентифицируется запрашиваемым URI. Данные - результат запроса - разбираются как XML-документ, и дерево конструируется в соответствии с моделью данных (см. [3 Модель Данных]). Если при запросе ресурса имеется ошибка, то XSLT-процессор может сигнализировать об ошибке; если он не сигнализирует об ошибке, он обязан вернуть пустой node-set. Один из возможных вариантов ошибки запроса - когда XSLT-процессор не поддерживает URI-схему, используемую данным URI. XSLT-ролцессор не обязан поддерживать каждую URI-схему. Документ для XSLT-процессора должен специфицировать, какие URI-схемы поддерживаются данным XSLT-процессором.

Если URI-ссылка не содержит идентификатор фрагмента, то возвращается набор узлов/node-set, содержащий только корневой узел документа. Если URI-ссылка содержит идентификатор фрагмента, эта функция возвращает node-set, содержащий узлы дерева, идентифицированные идентификатором фрагмента этой URI-ссылки. Семантика идентификатора фрагмента зависит от типа носителя (media type) результат запроса URI. Если возникает шибка про обработке идентификатора фрагмента, XSLT-процессор сигнализировать об этом; если он не сигнализирует об ошибке, он обязан вернуть пустой node-set. Среди возможных ошибок:

Данные - результат выполнения запроса - разбираются как XML-документ вне зависимости от типа носителя результата; если тип носителя верхнего уровня - text, то он разбирается так же, как если бы тип носителя был text/xml; иначе он разбирается так же, как если бы тип носителя был application/xml.

ПРИМЕЧАНИЕ: поскольку отсутствует тип носителя xml верхнего уровня, данные с типом носителя, отличным от text/xml или application/xml, могут фактически быть XML.

URI-ссылка может быть относительной. Базовый URI (см. [3.2 Базовый URI]) узла во втором наборе узлов аргумента, т.е. первый в порядке документа, используется как базовый URI для расширения относительного URI в абсолютный URI. Если второй аргумент опущен, то по умолчанию это будет тот узел таблицы стилей, который содержит выражение, включающее вызов функции document. Обратите внимание, что URI-ссылка нулевой длины является ссылкой на документ, относительно которого разрешается URI-ссылка; таким образом, document("") ссылается на корневой узел таблицы стилей; представление таблицы стилей в виде дерева - точно такое же, как если бы XML-документ, содержащий таблицу стилей, был начальным документом-источником.

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

generate-id(document("foo.xml"))=generate-id(document("foo.xml"))

Функция document даёт возможность набору узлов/node-set содержать узлы из более чем одного документа. С таким node-set относительный порядок документа двух узлов в одном и том же документе является нормальным document order/порядком документа, определённым в XPath [XPath]. Относительный порядок документа двух узлов в различных документах определяется конкретной реализацией упорядочивания документов, содержащих эти узлы. Нет ограничений на то, как упорядочиваются документы, кроме того, что это должно делаться последовательно: реализация обязана всегда использовать тот же порядок для одного набора документов.

12.2 Ключи

Ключи это способ работы с документами, содержащими структуру неявных перекрёстных ссылок. Типы атрибутов ID, IDREF и IDREFS в XML предоставляют механизм, дающий возможность XML-документам делать перекрёстную ссылку явной. XSLT поддерживает это с помощью функции XPath id. Однако в этом механизме имеется ряд ограничений:

Из-за этих ограничений XML-документы иногда могут иметь перекрёстно-ссылочную структуру, которая не объявлена явным образом атрибутами ID/IDREF/IDREFS.

Ключ содержит:

  1. узел, имеющий ключ

  2. имя ключа (expanded-name/развёрнутое имя)

  3. значение ключа (строку)

Таблица стилей объявляет набор ключей для каждого документа с помощью элемента xsl:key. Если этот набор ключей содержит члена узла x с именем y и значением z, мы говорим, что узел x имеет ключ с именем y и значением z.

Таким образом, ключ является своего рода генерализованным ID, который не является субъектом ограничений для XML ID:

<!-- Category: top-level-element -->
<xsl:key
  name = qname
  match = pattern
  use = expression />

Для объявления ключей используется элемент xsl:key. Атрибут name специфицирует имя ключа. Значением атрибута name является QName, которое разворачивается, как описано в разделе [2.4 Квалифицированные Имена]. Атрибут match это Патэрн; элемент xsl:key предоставляет информацию о ключах любого узла, совпадающего с патэрном, специфицированным в атрибуте match. Атрибут use это выражение, специфицирующее значения ключа; выражение вычисляется один раз для каждого узла, совпадающего с патэрном. Если результатом является node-set/набор узлов, то каждый узел набора узлов, совпадающий с патэрном, имеет ключ со специфицированным именем, значением которого является строковое значение узла в наборе узлов; иначе результат конвертируется в строку, а узел совпадающий с патэрном, имеет ключ со специфицированным именем, значение которого равно этой строке. Таким образом, узел x имеет ключ по имени y со значением z, если, и только если, имеется элемент xsl:key, где:

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

Для значения атрибута use или атрибута match является ошибкой, если атрибут содержит VariableReference.

Функция: node-set key(string, object)

Функция key работает для ключей так же, как функция id работает для ID-ов. Первый аргумент специфицирует имя ключа. Значением аргумента обязано быть QName, которое разворачивается, как указано в разделе [2.4 Квалифицированные Имена]. Если второй аргумент функции key имеет тип node-set, то результатом является union/объединение результата применения функции key к строковому значению каждого узла в аргументе node-set. Если второй аргумент функции key - любого другого типа, этот аргумент конвертируется в строку, как при вызове функции string; он возвращает node-set, содержащий узлы того же документа, что и контекстный узел, имеющий значение для именованного ключа, равное этой строке.

Например, имея объявление

<xsl:key name="idkey" match="div" use="@id"/>

выражение key("idkey",@ref) будет возвращать тот же node-set что и id(@ref), принимая, что единственным атрибутом ID, объявленным в исходном XML-документе, является:

<!ATTLIST div id ID #IMPLIED>

и атрибут ref текущего узла не содержит пробелов.

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

<prototype name="key" return-type="node-set">
<arg type="string"/>
<arg type="object"/>
</prototype>

и элемент function - для обращения к именам

<function>key</function>

Тогда таблица стилей может сгенерировать гиперссылки между ссылками и определениями:

<xsl:key name="func" match="prototype" use="@name"/>

<xsl:template match="function">
<b>
  <a href="#{generate-id(key('func',.))}">
    <xsl:apply-templates/>
  </a>
</b>
</xsl:template>

<xsl:template match="prototype">
<p><a name="{generate-id()}">
<b>Функция: </b>
...
</a></p>
</xsl:template>

Функция key может использоваться для запрашивания ключа из документа, иного, нежели документ, содержащий context-узел. Например, документ содержит библиографические ссылки в форме <bibref>XSLT</bibref>, и имеется отдельный XML-документ bib.xml содержит библиографическую базу данных с вхождениями в форме:

<entry name="XSLT">...</entry>

Тогда таблица стилей может использовать следующее для трансформации элементов bibref:

<xsl:key name="bib" match="entry" use="@name"/>

<xsl:template match="bibref">
  <xsl:variable name="name" select="."/>
  <xsl:for-each select="document('bib.xml')">
    <xsl:apply-templates select="key('bib',$name)"/>
  </xsl:for-each>
</xsl:template>

12.3 Форматирование Чисел

Функция: string format-number(number, string, string?)

Функция format-number конвертирует свой первый аргумент в строку с использованием строки патэрна формата, специфицированной вторым аргументом, и десятеричного формата, именованным третьим аргументом, или десятеричного формата по умолчанию, если третий аргумент отсутствует. Строка патэрна формата имеет синтаксис, специфицированный классом JDK 1.1 DecimalFormat. Строка патэрна формата имеет локализованную нотацию: десятеричный формат определяет, какие символы имеют специальное значение в этом патэрне (за исключением символа кавычки/quote, который не локализован). Патэрн формата обязан не содержать знак валюты/currency (#x00A4); поддержка этого была добавлена после начального релиза JDK 1.1. Имя десятеричного формата обязано быть QName, которое разворачивается, как указано в разделе [2.4 Квалифицированные Имена]. Является ошибкой, если таблица стилей не содержит объявление десятеричного формата со специфицированным expanded-name.

ПРИМЕЧАНИЕ: не обязательно, чтобы реализации использовали реализации JDK 1.1 и чтобы они были реализациями, обязательно реализованными в Java.
ПРИМЕЧАНИЕ: таблицы стилей могут использовать другие средства XPath для управления округлением.

<!-- Category: top-level-element -->
<xsl:decimal-format
  name = qname
  decimal-separator = char
  grouping-separator = char
  infinity = string
  minus-sign = char
  NaN = string
  percent = char
  per-mille = char
  zero-digit = char
  digit = char
  pattern-separator = char />

Элемент xsl:decimal-format объявляет десятичный формат, управляющий интерпретацией патэрна формата, используемого функцией format-number . Если имеется атрибут name, то этот элемент объявляет именованный десятичный формат; иначе он объявляет decimal-format по умолчанию. Значением атрибута name является QName, которое разворачивается, как указано в разделе [2.4 Квалифицированные Имена]. Ошибкой является объявление десятичный формат по умолчанию или десятичный формат с заданным именем более одного раза (даже с разными приоритетами импорта), если только он не объявляется каждый раз с тем же значением для всех атрибутов (с учётом любых значений по умолчанию).

Другие атрибуты элемента xsl:decimal-format соответствуют методам класса JDK 1.1 DecimalFormatSymbols. Для каждой пары методов get/set имеется атрибут, определённый для элемента xsl:decimal-format.

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

Следующие атрибуты управляют интерпретацией символов патэрна формата:

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

12.4 Прочие Дополнительные Функции

Функция: node-set current()

Функция current возвращает node-set/набор узлов, который содержит текущий узел в качестве единственного члена. Для самого внешнего выражения (выражения, не находящегося внутри другого выражения) текущий узел/current node - всегда тот же, что и узел контекста. Таким образом,

<xsl:value-of select="current()"/>

означает то же, что

<xsl:value-of select="."/>

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

<xsl:apply-templates select="//glossary/item[@name=current()/@ref]"/>

обработает все элементы item, имеющие родительский элемент glossary и атрибут name со значением, равным значению атрибута ref текущего узла. Вот другая форма

<xsl:apply-templates select="//glossary/item[@name=./@ref]"/>

которая означает то же, что и

<xsl:apply-templates select="//glossary/item[@name=@ref]"/>

и будет обрабатывать все элементы item, имеющие родительский элемент glossary и атрибут name и атрибут ref с тем же значением.

Ошибкой является использование функции current в патэрне.

Функция: string unparsed-entity-uri(string)

unparsed-entity-uri возвращает URI неразобранного экземпляра со специфицированным именем в том же документе, что узел контекста (см. [3.3 Неразбираемые Экземпляры]). Она возвращает пустую строку, если такого экземпляра нет.

Функция: string generate-id(node-set?)

generate-id возвращает строку, уникально идентифицирующую узел в аргументе node-set/набор узлов, стоящий первым в порядке документа. Уникальный идентификатор обязан состоять из алфавитно-цифровых символов ASCII и обязан начинаться алфавитным символом. Таким образом, эта строка синтаксически является XML-именем. Реализации свободны в определении подходящего способа генерации идентификатора, гарантируя, что всегда генерируется тот же идентификатор для того же узла и что различные идентификаторы всегда генерируются из различных узлов. Нет требования обязательно генерировать те же самые идентификаторы всякий раз при трансформации документа. Нет никаких гарантий, что сгенерированный уникальный идентификатор будет отличаться от любого уникального ID, специфицированного в документе-источнике. Если аргумент node-set пустой, возвращается пустая строка. Если аргумент опущен, он содержит по умолчанию узел контекста.

Функция: object system-property(string)

Аргумент обязан вычисляться в строку, которая является QName. Это QName разворачивается в имя с использованием объявлений пространства имён в области видимости данного выражения. Функция system-property возвращает объект, представляющий значение системного свойства, идентифицированного по имени. Если такого системного свойства нет, должна возвращаться пустая строка.

Реализации обязаны предоставлять следующие системные свойства, которые находятся в XSLT-пространстве имён:

13 Сообщения

<!-- Category: instruction -->
<xsl:message
  terminate = "yes" | "no">
  <!-- Content: template -->
</xsl:message>

Инструкция xsl:message отправляет сообщение способом, зависящим от XSLT-процессора. Содержимое инструкции xsl:message является шаблоном. Экземпляр xsl:message создаётся путём инстанциации (создания экземпляра) содержимого для создания XML-фрагмента. Этот XML-фрагмент является содержимым сообщения.

ПРИМЕЧАНИЕ: XSLT-процессор может реализовывать xsl:message путём вывода предупреждающего сообщения или записи в лог-файл.

Если атрибут terminate имеет значение yes, то XSLT-процессор должен прервать обработку после отправки сообщения. Значение по умолчанию - no.

Удобный способ локализации - поместить локализованную информацию (текст сообщения etc.) в XML-документ, который становится дополнительным input-файлом для таблицы стилей. Например, предположим, что сообщения на языке L хранятся в XML-файле resources/L.xml в форме:

<messages>
  <message name="problem">A problem was detected.</message>
  <message name="error">An error was detected.</message>
</messages>

Таблица стилей может использовать следующий подход для локализации этих сообщений:

<xsl:param name="lang" select="en"/>
<xsl:variable name="messages"
  select="document(concat('resources/', $lang, '.xml'))/messages"/>

<xsl:template name="localized-message">
  <xsl:param name="name"/>
  <xsl:message>
    <xsl:value-of select="$messages/message[@name=$name]"/>
  </xsl:message>
</xsl:template>

<xsl:template name="problem">
  <xsl:call-template name="localized-message"/>
    <xsl:with-param name="name">problem</xsl:with-param>
  </xsl:call-template>
</xsl:template>

14 Расширения

XSLT допускает расширения двух видов: расширение элементов и расширение.

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

14.1 Расширение Элементов

Механизм расширения элементов позволяет назначать пространства имён как extension namespace/пространства имён расширений. Если пространство имён/namespace назначено как extension namespace и элемент с именем из этого пространства имён появляется в шаблоне, то этот элемент рассматривается как инструкция, а не как литеральный результирующий элемент. Пространство имён определяет семантику инструкции.

ПРИМЕЧАНИЕ: поскольку элемент, являющийся дочерним для элемента xsl:stylesheet, не появляется в шаблоне, не-XSLT-элементы верхнего уровня не являются элементами расширения, как определено здесь, и ничто из этого раздела не применяется к ним.

Пространство имён назначается как пространство имён расширений с помощью атрибута extension-element-prefixes элемента xsl:stylesheet или атрибута xsl:extension-element-prefixes литерального результирующего элемента или элемента расширения. Значением обоих этих атрибутов является разделённый пробелами список префиксов пространства имён. Пространство имён, ограничивающее каждый префикс, назначается как пространство имён расширения. Является ошибкой, если отсутствует граница пространства имён для префикса в элементе, владельце атрибута extension-element-prefixes или xsl:extension-element-prefixes. По умолчанию пространство имён (как объявлено xmlns) может быть назначено пространство имён расширения путём включения #default в список префиксов пространства имён. Назначение пространства имён пространством имён расширения эффективно внутри поддерева таблицы стилей, начинающегося с элемента, порождающего атрибут extension-element-prefixes или xsl:extension-element-prefixes; поддерево, имеющее в корне элемент xsl:stylesheet, не включает в себя никаких таблиц стилей, импортированных или подключённых/include потомками этого элемента xsl:stylesheet.

Если XSLT-процессор не имеет реализации конкретного доступного элемента расширения, то функция element-available обязана возвращать для имени такого элемента. Если такой элемент расширения инстанциирован (создан его экземпляр), то XSLT-процессор обязан выполнить откат/fallback для этого элемента, как специфицировано в разделе [15 Откат]. XSLT-процессор не обязан явно сигнализировать об ошибке, поскольку шаблон содержит элемент расширения, для которого отсутствует доступная реализация.

Если XSLT-процессор имеет реализацию для конкретного доступного элемента расширения, то функция element-available обязана возвращать true для имени такого элемента.

14.2 Расширение Функций

Если FunctionName в выражении FunctionCall не является NCName (т.е. если содержит двоеточие), то оно рассматривается как вызов функции расширения. FunctionName разворачивается в имя с помощью объявлений пространства имён из контекста вычислений.

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

Если XSLT-процессор имеет реализацию функции расширения конкретного доступного имени, то функция function-available обязана возвращать true для такого имени. Если такое расширение вызывается, то XSLT-процессор обязан вызвать реализацию, передавая её аргументы вызова функции; результат, возвращаемый реализацией, возвращается как результат вызова функции.

15 Откат

<!-- Category: instruction -->
<xsl:fallback>
  <!-- Content: template -->
</xsl:fallback>

Нормально инстанциация (создание экземпляра) элемента xsl:fallback ничего не делает. Однако, если XSLT-процессор выполняет откат/fallback для элемента инструкции, если элемент инструкции имеет один или более дочерних xsl:fallback, то содержимое каждого дочернего xsl:fallback обязано быть последовательно инстанциировано; иначе должен быть выдан сигнал об ошибке. Содержимым элемента xsl:fallback является шаблон.

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

Функция: boolean element-available(string)

Аргумент обязан вычисляться в строку, которая является QName. Это QName разворачивается в expanded-name/развёрнутое имя с помощью объявлений пространства имён в области видимости выражения. Функция element-available возвращает true, если, и только если, expanded-name это имя инструкции. Если expanded-name имеет URI пространства имён, равный URI пространства имён XSLT, то он ссылается на элемент, определённый XSLT. Иначе он ссылается на элемент расширения. Если expanded-name имеет нулевой URI пространства имён, то функция element-available возвратит false.

Функция: boolean function-available(string)

Аргумент обязан вычисляться в строку, которая является QName. Это QName разворачивается в expanded-name/развёрнутое имя с помощью объявлений пространства имён в области видимости выражения. Функция function-available возвращает true, если, и только если, expanded-name это имя функции в библиотеке . Если expanded-name имеет ненулевой URI пространства имён, то он ссылается на функцию расширения; иначе он ссылается на функцию, определённую XPath или XSLT.

16 Вывод

<!-- Category: top-level-element -->
<xsl:output
  method = "xml" | "html" | "text" | qname-but-not-ncname
  version = nmtoken
  encoding = string
  omit-xml-declaration = "yes" | "no"
  standalone = "yes" | "no"
  doctype-public = string
  doctype-system = string
  cdata-section-elements = qnames
  indent = "yes" | "no"
  media-type = string />

XSLT-процессор может выводить результирующее дерево как последовательность байтов, хотя это не является обязательным требованием (см. [17 Соответствие]). Элемент xsl:output даёт возможность авторам таблиц стилей специфицировать, как выводить результирующее дерево. Если XSLT-процессор выводит результирующее дерево, он должен делать это так, как специфицировано элементом xsl:output; это, однако, не является обязательным требованием.

Элемент xsl:output доступен только как элемент верхнего уровня.

Атрибут method элемента xsl:output идентифицирует общий метод, который должен использоваться для вывода результирующего дерева. Значением обязано быть QName. Если QName не имеет префикса, то оно идентифицирует метод, специфицированный в данном документе, и это должен быть xml, html или text. Если QName имеет префикс, то QName разворачивается в expanded-name/развёрнутое имя, как описано в разделе [2.4 Квалифицированные Имена]; expanded-name идентифицирует метод вывода; поведение в этом случае не специфицировано данным документом.

Значение по умолчанию для method избирается так. Если

то по умолчанию метод вывода будет html; иначе по умолчанию метод вывода будет xml. Метод вывода по умолчанию должен использоваться, если ни один элемент xsl:output или элемент xsl:output не специфицирует значение атрибута method.

Другие атрибуты элемента xsl:output предоставляют параметры для метола вывода. Допустимы следующие атрибуты:

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

Таблица стилей может содержать несколько элементов xsl:output и может подключать или импортировать таблицы стилей, также содержащие элементы xsl:output. Все элементы xsl:output, появляющиеся в таблице стилей, сращиваются в один элемент xsl:output. Для атрибута cdata-section-elements действующим значением является объединение специфицированных значений. Для других атрибутов действующим значением является специфицированное значение с наивысшим приоритетом импорта. Является ошибкой, если имеется более одного такого значения атрибута. XSLT-процессор может сигнализировать об ошибке; если он не сигнализирует об ошибке, он должен выполнять её обработку с использованием значения, появляющегося последним в таблице стилей. Устанавливаются значения по умолчанию атрибутов после сращивания элементов xsl:output; разные методы вывода могут иметь разные значения атрибутов.

16.1 Метод Вывода XML

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

<!DOCTYPE doc [
<!ENTITY e SYSTEM "entity-URI">
]>
<doc>&e;</doc>

где entity-URI это URI экземпляра, то документ-оболочка в целом должен быть правильно сформированным XML-документов, соответствующим XML Namespaces Recommendation [XML Names]. Кроме того, вывод должен быть таким, что, если новое дерево было сконструировано путём разбора оболочки как XML-документ, как специфицировано в разделе [3 Модель Данных], с удалением элемента document и созданием его дочерних элементов, вместо того чтобы делать дочерние узлы корневого узла, то новое дерево будет таким же, как результирующее дерево со следующими возможными исключениями:

Если XSLT-процессор сгенерировал объявление типа документа из-за наличия атрибута doctype-system, то вышеуказанное требование применяется к экземпляру с удалённым объявления объявлением типа документа.

Атрибут version специфицирует версию XML, используемую для вывода результирующего дерева. Если XSLT-процессор не поддерживает эту версию XML, он должен использовать версию XML, которую поддерживает. Версия вывода в объявлении XML (если XML-объявление является выводом) должна соответствовать версии XML, используемой процессором для вывода результирующего дерева. Значение атрибута version должно совпадать с продуктом VersionNum Рекомендаций XML Recommendation [XML]. значением по умолчанию является 1.0.

Атрибут encoding специфицирует предпочтительную кодировку при выводе результирующего дерева. XSLT-процессоры должны учитывать значения UTF-8 и UTF-16. Для других значений, если XSLT-процессор не поддерживает специфицированную кодировку, он может сообщать об ошибке; если он не сообщает об ошибке, он использовать UTF-8 или UTF-16. XSLT-процессор не обязан использовать кодировку, имя которой не соответствует продукту EncName Рекомендаций XML Recommendation [XML]. Если атрибут encoding не специфицирован, XSLT-процессор должен использовать UTF-8 или UTF-16. Возможно, что результирующее дерево будет содержать символ, который не может быть представлен в кодировке, используемой XSLT-процессором для вывода. В этом случае, если этот символ появляется в контексте, где XML распознаёт символьные ссылки (т.е. в значении узла атрибутов или текстовом узле), этот символ должен быть выведен как ссылка на символ; иначе (например, если символ появляется в имени элемента) XSLT-процессор должен сигнализировать об ошибке.

Если атрибут indent имеет значение yes, то метод вывода xml может вывести пробел в дополнение к имеющемуся пробелу в результирующем дереве (возможно, базируясь на пробеле, вырезанном из исходного документа или из таблицы стилей), чтобы правильно расположит отступ; если атрибут indent имеет значение no, дополнительный пробел не должен выводиться. По умолчанию значение no. Метод вывода xml должен использовать такой алгоритм вывода дополнительного пробела, чтобы гарантировать, что результат (если пробелы были вырезаны из вывода с использованием процесса, описанного в разделе [3.4 Вырезание Пробелов], с набором элементов, сохраняющих пробелы, состоящим из xsl:text), был бы одинаковым при выводе дополнительного пробела и при отсутствии его вывода.

ПРИМЕЧАНИЕ: чаще всего ненадёжным является использование indent="yes" с документами типов, имеющих смешанное/mixed содержимое.

Атрибут cdata-section-elements содержит список разделённых пробелами QNames. Каждое QName разворачивается в expanded-name с помощью объявлений пространства имён, действующего для элемента xsl:output, в котором появляется QName; если имеется пространство имён по умолчанию/default namespace, оно используется для QName-ов, не имеющих префикса. Разворачивание выполняется до сращивания нескольких элементов xsl:output в единый элемент xsl:output. Если expanded-name родителя текстового узла является членом этого списка, то текстовый узел должен выводиться как раздел CDATA. Например,

<xsl:output cdata-section-elements="example"/>

даст литеральный результирующий элемент, записанный в таблице стилей так

<example>&lt;foo></example>

или так

<example><![CDATA[<foo>]]></example>

даст на выводе

<example><![CDATA[<foo>]]></example>

Если текстовый узел содержит последовательность символов ]]>, то открытый в данный момент раздел CDATA должен быть закрыт с последующими ]], а новый раздел CDATA должен быть открыт перед >. Например, a литеральный результирующий элемент, записанный в таблице стилей так

<example>]]&gt;</example>

выведется так

<example><![CDATA[]]]]><![CDATA[>]]></example>

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

Разделы CDATA должны использоваться только для тех текстовых узлов, которые явно специфицированы атрибутом cdata-section-elements как разделы, которые должны выводиться как разделы CDATA.

Метод xml должен выводить XML-объявление, если атрибут omit-xml-declaration не имеет значение yes. XML-объявление должно включать информацию версии и объявление кодировки. Если специфицирован атрибут standalone, должно включаться объявление отдельного/standalone документа с тем же значением, что значение атрибута standalone. Иначе объявление standalone-документа не должно включаться; это гарантирует, что имеются как XML-объявление (разрешённое в начале экземпляра документа), так и текстовое объявление (разрешённое в начале внешнего общего разбираемого экземпляра).

Если специфицирован атрибут doctype-system, метод вывода xml должен выводить объявление типа документа непосредственно перед первым элементом. Имя, идущее после <!DOCTYPE , должно быть именем первого элемента. Если атрибут doctype-public также специфицирован, то метод вывода xml должен вывести PUBLIC с последующим public-идентификатором, а затем - системный идентификатор; иначе - должен вывести SYSTEM с последующим системным идентификатором. Внутренний поднабор/subset должен быть пустым. Атрибут doctype-public должен игнорироваться, если только не специфицирован атрибут doctype-system.

Атрибут media-type применяется для метода вывода xml. Значением по умолчанию для атрибута media-type является text/xml.

16.2 Метод Вывода HTML

Метод вывода html выводит результирующее дерево как HTML; например,

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

<xsl:output method="html"/>

<xsl:template match="/">
  <html>
   <xsl:apply-templates/>
  </html>
</xsl:template>

...

</xsl:stylesheet>

Атрибут version указывает версию HTML. По умолчанию он имеет значение 4.0, которое специфицирует, что результат должен быть выведен как HTML, соответствующий Рекомендациям HTML 4.0 Recommendation [HTML].

Метод вывода html не должен выводить элемент отдельно от метода вывода xml, если только expanded-name элемента не имеет нулевой URI пространства имён; элемент, expanded-name/развёрнутое имя которого имеет ненулевой URI пространства имён, должно быть выведено как XML. Если expanded-name элемента имеет нулевой URI пространства имён, но локальная часть expanded-name не распознаётся как имя HTML-элемента, то элемент должен выводиться тем же способом, что и непустой inline-элемент, такой как span.

Метод вывода html не должен выводить конечные тэги пустых элементов. Для HTML 4.0 пустыми являются элементы area, base, basefont, br, col, frame, hr, img, input, isindex, link, meta и param. Например, элемент, записанный <br/> или <br></br> в таблице стилей должен выводиться <br>.

Метод вывода html должен распознавать имена HTML-элементов независимо от регистра символов. Например, элементы br, BR или Br должны все распознаваться как HTML-элемент br и выводиться без конечного тэга.

Метод вывода html не должен выполнять escapе-замену/escaping содержимого элементов script и style. Например, литеральный результирующий элемент, записанный в таблице стилей так

<script>if (a &lt; b) foo()</script>

или так

<script><![CDATA[if (a < b) foo()]]></script>

должен выводиться так

<script>if (a < b) foo()</script>

Метод вывода html не должен заменять/escape символы < в значениях атрибутов.

Если атрибут indent имеет значение yes, то метод вывода html может добавлять или удалять пробел при выводе результирующего дерева, пока не изменено то, как пользовательский агент (браузер) HTML должен представлять вывод. По умолчанию значение yes.

Метод вывода html должен заменять/escape не-ASCII символы в значениях URI-атрибута с использованием метода, рекомендованного в Разделе B.2.1 HTML 4.0 Recommendation.

Метод вывода html может выводить символ с использованием символьной мнемоники, если она определена для него в версии HTML, используемой методом вывода.

Метод вывода html должен прерывать инструкции процессинга знаком > вместо ?>.

Метод вывода html должен выводить булевы атрибуты (то есть атрибуты с единственным допустимым значением, эквивалентным имени этого атрибута) в минимизированной форме. Например, начальный тэг, записанный в таблице стилей так

<OPTION selected="selected">

должен быть выведен так

<OPTION selected>

Метод вывода html не должен заменять/escape символ & в значении атрибута, когда сразу за этим символом идёт символ { (см. Раздел B.7.1 HTML 4.0 Recommendation). Например, начальный тэг, записанный в таблице стилей так

<BODY bgcolor='&amp;{{randomrbg}};'>

должен быть выведен так

<BODY bgcolor='&{randomrbg};'>

Атрибут encoding специфицирует приоритетную используемую кодировку символов. Если имеется элемент HEAD, то метод вывода html должен добавлять элемент META сразу после начального тэга элемента HEAD, специфицируя используемую кодировку символов. Например,

<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
...

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

Если специфицированы атрибуты doctype-public или doctype-system, то метод вывода html должен выводить объявление типа документа непосредственно перед первым элементом. Имя идущее после <!DOCTYPE , должно быть HTML или html. Если специфицирован атрибут doctype-public, метод вывода должен вывести PUBLIC с последующим специфицированным public-идентификатором; если атрибут doctype-system также специфицирован, должен выводиться также специфицированный системный идентификатор с последующим public-идентификатором. Если специфицирован атрибут doctype-system, но атрибут doctype-public не специфицирован, метод вывода должен вывести SYSTEM с последующим специфицированным системным идентификатором.

Атрибут media-type применяется для метода вывода html. По умолчанию значение text/html.

16.3 Метод Вывода Text

Метод вывода text выводит результирующее дерево, выводя строковое значение каждого текстового узла результирующего дерева документа без замен/escaping.

Атрибут media-type применяется для метода вывода text. Значением по умолчанию атрибута media-type является text/plain.

Атрибут encoding идентифицирует кодировку символов, которую метод вывода text должен использовать для конвертации последовательностей символов в последовательности байтов. По умолчанию - системная кодировка/system-dependent. Если результирующее дерево содержит символ, который не может быть представлен в кодировке, используемой XSLT-процессором для вывода, XSLT-процессор должен сигнализировать об ошибке.

16.4 Отключение Escapе-ирования/Мнемонизации в Выводе

Обычно метод вывода xml заменяет/escape символы & и < (и, возможно, другие символы) при выводе текстовых узлов. Это гарантирует, что на выводе будет правильно сформированный XML. Однако иногда бывает удобно иметь возможность создать такой вывод, который является почти, но не полностью, правильно сформированным XML; например, вывод может содержать неправильно сформированные разделы, которые предполагается трансформировать в правильно сформированный XML последующим не-XML процессом. Исходя из этого, XSLT предоставляет механизм отключения escapi-рования на выводе. Элемент xsl:value-of или xsl:text может иметь атрибут disable-output-escaping; допустимы значения yes или no; по умолчанию no; если yes, то текстовый узел, сгенерированный инстанциацией (созданием экземпляра) элемента xsl:value-of или xsl:text, должен выводиться без escapi-рования. Например,

<xsl:text disable-output-escaping="yes">&lt;</xsl:text>

должен сгенерировать единственный символ <.

Для мнемонизации/escaping вывода является ошибкой, если она выключена для текстового узла и используется ещё для чего-нибудь, кроме текстового узла, в результирующем дереве. Таким образом, будет ошибкой отключение мнемонизации/escaping для элемента xsl:value-of или xsl:text, который используется для генерации строкового значения комментария, инструкции процессинга или узла атрибутов; также ошибкой является конвертация фрагмента результирующего дерева в число или строку, когда фрагмент результирующего дерева содержит текстовый узел, для которого мнемонизация/escaping была отключена. В обоих случаях XSLT-процессор может сигнализировать об ошибке; если он не сигнализирует об ошибке, он обязан исправить ошибку, игнорируя атрибут disable-output-escaping.

Атрибут disable-output-escaping может использоваться с методом вывода html, также как и с методом вывода xml. Метод вывода text игнорирует атрибут disable-output-escaping, поскольку он не выполняет никакой мнемонизации вывода.

XSLT-процессор сможет только тогда отключать мнемонизацию вывода, когда он контролирует вывод результирующего дерева. Но так бывает не всегда. Например, результирующее дерево может использоваться как исходное дерево для другой XSLT-трансформации вместо вывода. XSLT-процессор не обязан поддерживать отключение мнемонизации вывода. Если xsl:value-of или xsl:text специфицирует, что мнемонизация вывода должна быть отключена и XSLT-процессор не поддерживает это, XSLT-процессор может сигнализировать об ошибке; если он не сигнализирует об ошибке, он обязан исправить ошибку, не отключая мнемонизацию вывода.

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

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

17 Соответствие

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

ПРИМЕЧАНИЕ: продавцам XSLT-процессоров настоятельно рекомендуется предоставлять способ проверки того, что их процессоры работают соответствующим образом, давая возможность выводить результирующее дерево как XML или предоставляя доступ к результирующему дереву через стандартный API, такой как DOM или SAX.

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

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

18 Нотация

Спецификации каждого определённого XSLT типа элемента предшествует резюме его синтаксиса в форме модели для элементов данного типа. Значение резюме синтаксиса нотации таково:


A Ссылки

A.1 Нормативные Ссылки

XML
World Wide Web Consortium. Extensible Markup Language (XML) 1.0. W3C Recommendation. См. http://www.w3.org/TR/1998/REC-xml-19980210
XML Names
World Wide Web Consortium. Namespaces in XML. W3C Recommendation. См. http://www.w3.org/TR/REC-xml-names
XPath
World Wide Web Consortium. XML Path Language. W3C Recommendation. См. http://www.w3.org/TR/xpath

A.2 Прочие Ссылки

CSS2
World Wide Web Consortium. Cascading Style Sheets, level 2 (CSS2). W3C Recommendation. См. http://www.w3.org/TR/1998/REC-CSS2-19980512
DSSSL
International Organization for Standardization, International Electrotechnical Commission. ISO/IEC 10179:1996. Document Style Semantics and Specification Language (DSSSL). International Standard.
HTML
World Wide Web Consortium. HTML 4.0 specification. W3C Recommendation. См. http://www.w3.org/TR/REC-html40
IANA
Internet Assigned Numbers Authority. Character Sets. См. ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets.
RFC2278
N. Freed, J. Postel. IANA Charset Registration Procedures. IETF RFC 2278. См. http://www.ietf.org/rfc/rfc2278.txt.
RFC2376
E. Whitehead, M. Murata. XML Media Types. IETF RFC 2376. См. http://www.ietf.org/rfc/rfc2376.txt.
RFC2396
T. Berners-Lee, R. Fielding, and L. Masinter. Uniform Resource Identifiers (URI): Generic Syntax. IETF RFC 2396. См. http://www.ietf.org/rfc/rfc2396.txt.
UNICODE TR10
Unicode Consortium. Unicode Technical Report #10. Unicode Collation Algorithm. Unicode Technical Report. См. http://www.unicode.org/unicode/reports/tr10/index.html.
XHTML
World Wide Web Consortium. XHTML 1.0: The Extensible HyperText Markup Language. W3C Proposed Recommendation. См. http://www.w3.org/TR/xhtml1
XPointer
World Wide Web Consortium. XML Pointer Language (XPointer). W3C Working Draft. См. http://www.w3.org/TR/xptr
XML Stylesheet
World Wide Web Consortium. Associating stylesheets with XML documents. W3C Recommendation. См. http://www.w3.org/TR/xml-stylesheet
XSL
World Wide Web Consortium. Extensible Stylesheet Language (XSL). W3C Working Draft. См. http://www.w3.org/TR/WD-xsl

B Синтаксис Элементов. Резюме.

<!-- Category: instruction -->
<xsl:apply-imports />

<!-- Category: instruction -->
<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

<!-- Category: instruction -->
<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  <!-- Content: template -->
</xsl:attribute>

<!-- Category: top-level-element -->
<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  <!-- Content: xsl:attribute* -->
</xsl:attribute-set>

<!-- Category: instruction -->
<xsl:call-template
  name = qname>
  <!-- Content: xsl:with-param* -->
</xsl:call-template>

<!-- Category: instruction -->
<xsl:choose>
  <!-- Content: (xsl:when+, xsl:otherwise?) -->
</xsl:choose>

<!-- Category: instruction -->
<xsl:comment>
  <!-- Content: template -->
</xsl:comment>

<!-- Category: instruction -->
<xsl:copy
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:copy>

<!-- Category: instruction -->
<xsl:copy-of
  select = expression />

<!-- Category: top-level-element -->
<xsl:decimal-format
  name = qname
  decimal-separator = char
  grouping-separator = char
  infinity = string
  minus-sign = char
  NaN = string
  percent = char
  per-mille = char
  zero-digit = char
  digit = char
  pattern-separator = char />

<!-- Category: instruction -->
<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:element>

<!-- Category: instruction -->
<xsl:fallback>
  <!-- Content: template -->
</xsl:fallback>

<!-- Category: instruction -->
<xsl:for-each
  select = node-set-expression>
  <!-- Content: (xsl:sort*, template) -->
</xsl:for-each>

<!-- Category: instruction -->
<xsl:if
  test = boolean-expression>
  <!-- Content: template -->
</xsl:if>

<xsl:import
  href = uri-reference />

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

<!-- Category: top-level-element -->
<xsl:key
  name = qname
  match = pattern
  use = expression />

<!-- Category: instruction -->
<xsl:message
  terminate = "yes" | "no">
  <!-- Content: template -->
</xsl:message>

<!-- Category: top-level-element -->
<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />

<!-- Category: instruction -->
<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

<xsl:otherwise>
  <!-- Content: template -->
</xsl:otherwise>

<!-- Category: top-level-element -->
<xsl:output
  method = "xml" | "html" | "text" | qname-but-not-ncname
  version = nmtoken
  encoding = string
  omit-xml-declaration = "yes" | "no"
  standalone = "yes" | "no"
  doctype-public = string
  doctype-system = string
  cdata-section-elements = qnames
  indent = "yes" | "no"
  media-type = string />

<!-- Category: top-level-element -->
<xsl:param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:param>

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

<!-- Category: instruction -->
<xsl:processing-instruction
  name = { ncname }>
  <!-- Content: template -->
</xsl:processing-instruction>

<xsl:sort
  select = string-expression
  lang = { nmtoken }
  data-type = { "text" | "number" | qname-but-not-ncname }
  order = { "ascending" | "descending" }
  case-order = { "upper-first" | "lower-first" } />

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

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

<!-- Category: top-level-element -->
<xsl:template
  match = pattern
  name = qname
  priority = number
  mode = qname>
  <!-- Content: (xsl:param*, template) -->
</xsl:template>

<!-- Category: instruction -->
<xsl:text
  disable-output-escaping = "yes" | "no">
  <!-- Content: #PCDATA -->
</xsl:text>

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

<!-- Category: instruction -->
<xsl:value-of
  select = string-expression
  disable-output-escaping = "yes" | "no" />

<!-- Category: top-level-element -->
<!-- Category: instruction -->
<xsl:variable
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:variable>

<xsl:when
  test = boolean-expression>
  <!-- Content: template -->
</xsl:when>

<xsl:with-param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:with-param>

C Фрагмент ОТД для Таблицы Стилей XSLT (ненормативное)

ПРИМЕЧАНИЕ: этот фрагмент DTD/ОТД (Определение Типа Данных) не является нормативным, так как XML 1.0 DTDs не поддерживают XML Namespaces и таким образом не могут описывать допустимые структуры таблиц стилей XSLT.

Следующий экземпляр/entity можно использовать для конструирования DTD для таблиц стилей XSLT, которые создают экземпляры DTD определённого результата. Прежде чем сослаться на entity, DTD таблицы стилей обязано определить экземпляр параметра result-elements, перечисляющий допустимые типы результирующих элементов. Например:

<!ENTITY % result-elements "
  | fo:inline-sequence
  | fo:block
">

Такие результирующие элементы должны объявляться как имеющие атрибуты xsl:use-attribute-sets и xsl:extension-element-prefixes. Нижеследующий экземпляр/entity объявляет для этой цели параметр result-element-atts. Содержимое, разрешённое XSLT для результирующих элементов, - то же, что разрешено для XSLT-элементов, объявленных в нижеследующем экземпляре с моделью содержимого %template;. DTD может использовать более строгую модель содержимого, нежели %template;, для отражения ограничений DTD результат.

DTD может определять экземпляр параметра non-xsl-top-level, чтобы разрешить дополнительные элементы верхнего уровня из пространств имён, отличных от пространства имён XSLT.

Использование префикса xsl: в этом DTD не подразумевает, что таблицы стилей XSLT обязаны использовать этот префикс. Любой элемент, объявленный в этом DTD, может иметь атрибуты, имена которых начинаются с xmlns: или эквивалентны xmlns, в дополнение к атрибутам, объявленным в этом DTD.

<!ENTITY % char-instructions "
  | xsl:apply-templates
  | xsl:call-template
  | xsl:apply-imports
  | xsl:for-each
  | xsl:value-of
  | xsl:copy-of
  | xsl:number
  | xsl:choose
  | xsl:if
  | xsl:text
  | xsl:copy
  | xsl:variable
  | xsl:message
  | xsl:fallback
">

<!ENTITY % instructions "
  %char-instructions;
  | xsl:processing-instruction
  | xsl:comment
  | xsl:element
  | xsl:attribute
">

<!ENTITY % char-template "
 (#PCDATA
  %char-instructions;)*
">

<!ENTITY % template "
 (#PCDATA
  %instructions;
  %result-elements;)*
">

<!-- Используется для значения атрибута, которое является URI-ссылкой. -->
<!ENTITY % URI "CDATA">

<!-- Используется для значения атрибута, которое является патэрном. -->
<!ENTITY % pattern "CDATA">

<!-- Используется для значения атрибута, которое является
     шаблоном значения атрибута. -->
<!ENTITY % avt "CDATA">

<!-- Используется для значения атрибута, которое является QName; этот префикс
     разворачивается XSLT-процессором. -->
<!ENTITY % qname "NMTOKEN">

<!-- Как qname, но разделённый пробелами список QNames. -->
<!ENTITY % qnames "NMTOKENS">

<!-- Используется для значения атрибута, которое является выражением. -->
<!ENTITY % expr "CDATA">

<!-- Используется для значения атрибута, которое состоит
     из единственного символа. -->
<!ENTITY % char "CDATA">

<!-- Используется для значения атрибута, которое является приоритетом. -->
<!ENTITY % priority "NMTOKEN">

<!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!-- Может быть переопределён для специализирования набора элементов,
     допустимых на верхнем уровне. -->

<!ENTITY % non-xsl-top-level "">

<!ENTITY % top-level "
 (xsl:import*,
  (xsl:include
  | xsl:strip-space
  | xsl:preserve-space
  | xsl:output
  | xsl:key
  | xsl:decimal-format
  | xsl:attribute-set
  | xsl:variable
  | xsl:param
  | xsl:template
  | xsl:namespace-alias
  %non-xsl-top-level;)*)
">

<!ENTITY % top-level-atts '
  extension-element-prefixes CDATA #IMPLIED
  exclude-result-prefixes CDATA #IMPLIED
  id ID #IMPLIED
  version NMTOKEN #REQUIRED
  xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
  %space-att;
'>

<!-- Этот экземпляр определён для использования в объявлении ATTLIST
     для результирующих элементов. -->

<!ENTITY % result-element-atts '
  xsl:extension-element-prefixes CDATA #IMPLIED
  xsl:exclude-result-prefixes CDATA #IMPLIED
  xsl:use-attribute-sets %qnames; #IMPLIED
  xsl:version NMTOKEN #IMPLIED
'>

<!ELEMENT xsl:stylesheet %top-level;>
<!ATTLIST xsl:stylesheet %top-level-atts;>

<!ELEMENT xsl:transform %top-level;>
<!ATTLIST xsl:transform %top-level-atts;>

<!ELEMENT xsl:import EMPTY>
<!ATTLIST xsl:import href %URI; #REQUIRED>

<!ELEMENT xsl:include EMPTY>
<!ATTLIST xsl:include href %URI; #REQUIRED>

<!ELEMENT xsl:strip-space EMPTY>
<!ATTLIST xsl:strip-space elements CDATA #REQUIRED>

<!ELEMENT xsl:preserve-space EMPTY>
<!ATTLIST xsl:preserve-space elements CDATA #REQUIRED>

<!ELEMENT xsl:output EMPTY>
<!ATTLIST xsl:output
  method %qname; #IMPLIED
  version NMTOKEN #IMPLIED
  encoding CDATA #IMPLIED
  omit-xml-declaration (yes|no) #IMPLIED
  standalone (yes|no) #IMPLIED
  doctype-public CDATA #IMPLIED
  doctype-system CDATA #IMPLIED
  cdata-section-elements %qnames; #IMPLIED
  indent (yes|no) #IMPLIED
  media-type CDATA #IMPLIED
>

<!ELEMENT xsl:key EMPTY>
<!ATTLIST xsl:key
  name %qname; #REQUIRED
  match %pattern; #REQUIRED
  use %expr; #REQUIRED
>

<!ELEMENT xsl:decimal-format EMPTY>
<!ATTLIST xsl:decimal-format
  name %qname; #IMPLIED
  decimal-separator %char; "."
  grouping-separator %char; ","
  infinity CDATA "Infinity"
  minus-sign %char; "-"
  NaN CDATA "NaN"
  percent %char; "%"
  per-mille %char; "&#x2030;"
  zero-digit %char; "0"
  digit %char; "#"
  pattern-separator %char; ";"
>

<!ELEMENT xsl:namespace-alias EMPTY>
<!ATTLIST xsl:namespace-alias
  stylesheet-prefix CDATA #REQUIRED
  result-prefix CDATA #REQUIRED
>

<!ELEMENT xsl:template
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:param)*
>

<!ATTLIST xsl:template
  match %pattern; #IMPLIED
  name %qname; #IMPLIED
  priority %priority; #IMPLIED
  mode %qname; #IMPLIED
  %space-att;
>

<!ELEMENT xsl:value-of EMPTY>
<!ATTLIST xsl:value-of
  select %expr; #REQUIRED
  disable-output-escaping (yes|no) "no"
>

<!ELEMENT xsl:copy-of EMPTY>
<!ATTLIST xsl:copy-of select %expr; #REQUIRED>

<!ELEMENT xsl:number EMPTY>
<!ATTLIST xsl:number
   level (single|multiple|any) "single"
   count %pattern; #IMPLIED
   from %pattern; #IMPLIED
   value %expr; #IMPLIED
   format %avt; '1'
   lang %avt; #IMPLIED
   letter-value %avt; #IMPLIED
   grouping-separator %avt; #IMPLIED
   grouping-size %avt; #IMPLIED
>

<!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>
<!ATTLIST xsl:apply-templates
  select %expr; "node()"
  mode %qname; #IMPLIED
>

<!ELEMENT xsl:apply-imports EMPTY>

<!-- xsl:sort не может появляться после любого другого элемента или
     любого непробельного символа. -->

<!ELEMENT xsl:for-each
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:sort)*
>

<!ATTLIST xsl:for-each
  select %expr; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:sort EMPTY>
<!ATTLIST xsl:sort
  select %expr; "."
  lang %avt; #IMPLIED
  data-type %avt; "text"
  order %avt; "ascending"
  case-order %avt; #IMPLIED
>

<!ELEMENT xsl:if %template;>
<!ATTLIST xsl:if
  test %expr; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:choose (xsl:when+, xsl:otherwise?)>
<!ATTLIST xsl:choose %space-att;>

<!ELEMENT xsl:when %template;>
<!ATTLIST xsl:when
  test %expr; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:otherwise %template;>
<!ATTLIST xsl:otherwise %space-att;>

<!ELEMENT xsl:attribute-set (xsl:attribute)*>
<!ATTLIST xsl:attribute-set
  name %qname; #REQUIRED
  use-attribute-sets %qnames; #IMPLIED
>

<!ELEMENT xsl:call-template (xsl:with-param)*>
<!ATTLIST xsl:call-template
  name %qname; #REQUIRED
>

<!ELEMENT xsl:with-param %template;>
<!ATTLIST xsl:with-param
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT xsl:variable %template;>
<!ATTLIST xsl:variable
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT xsl:param %template;>
<!ATTLIST xsl:param
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT xsl:text (#PCDATA)>
<!ATTLIST xsl:text
  disable-output-escaping (yes|no) "no"
>

<!ELEMENT xsl:processing-instruction %char-template;>
<!ATTLIST xsl:processing-instruction
  name %avt; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:element %template;>
<!ATTLIST xsl:element
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  use-attribute-sets %qnames; #IMPLIED
  %space-att;
>

<!ELEMENT xsl:attribute %char-template;>
<!ATTLIST xsl:attribute
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  %space-att;
>

<!ELEMENT xsl:comment %char-template;>
<!ATTLIST xsl:comment %space-att;>

<!ELEMENT xsl:copy %template;>
<!ATTLIST xsl:copy
  %space-att;
  use-attribute-sets %qnames; #IMPLIED
>

<!ELEMENT xsl:message %template;>
<!ATTLIST xsl:message
  %space-att;
  terminate (yes|no) "no"
>

<!ELEMENT xsl:fallback %template;>
<!ATTLIST xsl:fallback %space-att;>

D Примеры (ненормативное)

D.1 Пример Документа

Это пример таблицы стилей для трансформации документов, соответствующих простому DTD, в XHTML [XHTML]. Вот DTD:

<!ELEMENT doc (title, chapter*)>
<!ELEMENT chapter (title, (para|note)*, section*)>
<!ELEMENT section (title, (para|note)*)>
<!ELEMENT title (#PCDATA|emph)*>
<!ELEMENT para (#PCDATA|emph)*>
<!ELEMENT note (#PCDATA|emph)*>
<!ELEMENT emph (#PCDATA|emph)*>

Это таблица стилей:

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

<xsl:strip-space elements="doc chapter section"/>
<xsl:output
   method="xml"
   indent="yes"
   encoding="iso-8859-1"
/>

<xsl:template match="doc">
 <html>
   <head>
     <title>
       <xsl:value-of select="title"/>
     </title>
   </head>
   <body>
     <xsl:apply-templates/>
   </body>
 </html>
</xsl:template>

<xsl:template match="doc/title">
  <h1>
    <xsl:apply-templates/>
  </h1>
</xsl:template>

<xsl:template match="chapter/title">
  <h2>
    <xsl:apply-templates/>
  </h2>
</xsl:template>

<xsl:template match="section/title">
  <h3>
    <xsl:apply-templates/>
  </h3>
</xsl:template>

<xsl:template match="para">
  <p>
    <xsl:apply-templates/>
  </p>
</xsl:template>

<xsl:template match="note">
  <p class="note">
    <b>NOTE: </b>
    <xsl:apply-templates/>
  </p>
</xsl:template>

<xsl:template match="emph">
  <em>
    <xsl:apply-templates/>
  </em>
</xsl:template>

</xsl:stylesheet>

С таким входным документом

<!DOCTYPE doc SYSTEM "doc.dtd">
<doc>
<title>Document Title</title>
<chapter>
<title>Chapter Title</title>
<section>
<title>Section Title</title>
<para>This is a test.</para>
<note>This is a note.</note>
</section>
<section>
<title>Another Section Title</title>
<para>This is <emph>another</emph> test.</para>
<note>This is another note.</note>
</section>
</chapter>
</doc>

она даст следующий результат

<?xml version="1.0" encoding="iso-8859-1"?>
<html xmlns="http://www.w3.org/TR/xhtml1/strict">
<head>
<title>Document Title</title>
</head>
<body>
<h1>Document Title</h1>
<h2>Chapter Title</h2>
<h3>Section Title</h3>
<p>This is a test.</p>
<p class="note">
<b>NOTE: </b>This is a note.</p>
<h3>Another Section Title</h3>
<p>This is <em>another</em> test.</p>
<p class="note">
<b>NOTE: </b>This is another note.</p>
</body>
</html>

D.2 Пример Данных

Это пример трансформации некоторых данных, представленных в виде XML, с использованием трёх разных таблиц стилей XSLT для производства трёх различных представлений данных: HTML, SVG и VRML.

Вот входные данные:

<sales>

        <division id="North">
                <revenue>10</revenue>
                <growth>9</growth>
                <bonus>7</bonus>
        </division>

        <division id="South">
                <revenue>4</revenue>
                <growth>3</growth>
                <bonus>4</bonus>
        </division>

        <division id="West">
                <revenue>6</revenue>
                <growth>-1.5</growth>
                <bonus>2</bonus>
        </division>

</sales>

Следующая таблица стилей, использующая упрощённый синтаксис, описанный в разделе [2.3 Литеральный Результирующий Элемент Как Таблица Стилей], трансформирует данные в HTML:

<html xsl:version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      lang="en">
    <head>
	<title>Sales Results By Division</title>
    </head>
    <body>
	<table border="1">
	    <tr>
		<th>Division</th>
		<th>Revenue</th>
		<th>Growth</th>
		<th>Bonus</th>
	    </tr>
	    <xsl:for-each select="sales/division">
		<!-- order the result by revenue -->
		<xsl:sort select="revenue"
			  data-type="number"
			  order="descending"/>
		<tr>
		    <td>
			<em><xsl:value-of select="@id"/></em>
		    </td>
		    <td>
			<xsl:value-of select="revenue"/>
		    </td>
		    <td>
			<!-- highlight negative growth in red -->
			<xsl:if test="growth &lt; 0">
			     <xsl:attribute name="style">
				 <xsl:text>color:red</xsl:text>
			     </xsl:attribute>
			</xsl:if>
			<xsl:value-of select="growth"/>
		    </td>
		    <td>
			<xsl:value-of select="bonus"/>
		    </td>
		</tr>
	    </xsl:for-each>
	</table>
    </body>
</html>

Это HTML-вывод:

<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Sales Results By Division</title>
</head>
<body>
<table border="1">
<tr>
<th>Division</th><th>Revenue</th><th>Growth</th><th>Bonus</th>
</tr>
<tr>
<td><em>North</em></td><td>10</td><td>9</td><td>7</td>
</tr>
<tr>
<td><em>West</em></td><td>6</td><td style="color:red">-1.5</td><td>2</td>
</tr>
<tr>
<td><em>South</em></td><td>4</td><td>3</td><td>4</td>
</tr>
</table>
</body>
</html>

Следующая таблица стилей трансформирует данные в SVG:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/Graphics/SVG/SVG-19990812.dtd">

<xsl:output method="xml" indent="yes" media-type="image/svg"/>

<xsl:template match="/">

<svg width = "3in" height="3in">
    <g style = "stroke: #000000">
        <!-- draw the axes -->
        <line x1="0" x2="150" y1="150" y2="150"/>
        <line x1="0" x2="0" y1="0" y2="150"/>
        <text x="0" y="10">Revenue</text>
        <text x="150" y="165">Division</text>
        <xsl:for-each select="sales/division">
	    <!-- define some useful variables -->

	    <!-- the bar's x position -->
	    <xsl:variable name="pos"
	                  select="(position()*40)-30"/>

	    <!-- the bar's height -->
	    <xsl:variable name="height"
	                  select="revenue*10"/>

	    <!-- the rectangle -->
	    <rect x="{$pos}" y="{150-$height}"
                  width="20" height="{$height}"/>

	    <!-- the text label -->
	    <text x="{$pos}" y="165">
	        <xsl:value-of select="@id"/>
	    </text>

	    <!-- the bar value -->
	    <text x="{$pos}" y="{145-$height}">
	        <xsl:value-of select="revenue"/>
	    </text>
        </xsl:for-each>
    </g>
</svg>

</xsl:template>
</xsl:stylesheet>

SVG-вывод:

<svg width="3in" height="3in"
     xmlns="http://www.w3.org/Graphics/SVG/svg-19990412.dtd">
    <g style="stroke: #000000">
	<line x1="0" x2="150" y1="150" y2="150"/>
	<line x1="0" x2="0" y1="0" y2="150"/>
	<text x="0" y="10">Revenue</text>
	<text x="150" y="165">Division</text>
	<rect x="10" y="50" width="20" height="100"/>
	<text x="10" y="165">North</text>
	<text x="10" y="45">10</text>
	<rect x="50" y="110" width="20" height="40"/>
	<text x="50" y="165">South</text>
	<text x="50" y="105">4</text>
	<rect x="90" y="90" width="20" height="60"/>
	<text x="90" y="165">West</text>
	<text x="90" y="85">6</text>
    </g>
</svg>

Следующая таблица стилей трансформирует данные в VRML:

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

<!-- generate text output as mime type model/vrml, using default charset -->
<xsl:output method="text" encoding="UTF-8" media-type="model/vrml"/>

        <xsl:template match="/">#VRML V2.0 utf8

# externproto definition of a single bar element
EXTERNPROTO bar [
  field SFInt32 x
  field SFInt32 y
  field SFInt32 z
  field SFString name
  ]
  "http://www.vrml.org/WorkingGroups/dbwork/barProto.wrl"

# inline containing the graph axes
Inline {
        url "http://www.vrml.org/WorkingGroups/dbwork/barAxes.wrl"
        }

                <xsl:for-each select="sales/division">
bar {
        x <xsl:value-of select="revenue"/>
        y <xsl:value-of select="growth"/>
        z <xsl:value-of select="bonus"/>
        name "<xsl:value-of select="@id"/>"
        }
                </xsl:for-each>

        </xsl:template>

</xsl:stylesheet>

VRML-вывод:

#VRML V2.0 utf8

# externproto definition of a single bar element
EXTERNPROTO bar [
  field SFInt32 x
  field SFInt32 y
  field SFInt32 z
  field SFString name
  ]
  "http://www.vrml.org/WorkingGroups/dbwork/barProto.wrl"

# inline containing the graph axes
Inline {
        url "http://www.vrml.org/WorkingGroups/dbwork/barAxes.wrl"
        }


bar {
        x 10
        y 9
        z 7
        name "North"
        }

bar {
        x 4
        y 3
        z 4
        name "South"
        }

bar {
        x 6
        y -1.5
        z 2
        name "West"
        }

E Благодарности (ненормативное)

В качестве авторов этого проекта были привлечены:

Эта спецификация была разработана и подготовлена к публикации Рабочей Группой W3C XSL (WG). Одобрение WG данной спецификации не означает, что все члены WG голосовали за одобрение.

Членами XSL WG на данный момент являются:

Sharon Adler, IBM (Co-Chair); Anders Berglund, IBM; Perin Blanchard, Novell; Scott Boag, Lotus; Larry Cable, Sun; Jeff Caruso, Bitstream; James Clark; Peter Danielsen, Bell Labs; Don Day, IBM; Stephen Deach, Adobe; Dwayne Dicks, SoftQuad; Andrew Greene, Bitstream; Paul Grosso, Arbortext; Eduardo Gutentag, Sun; Juliane Harbarth, Software AG; Mickey Kimchi, Enigma; Chris Lilley, W3C; Chris Maden, Exemplary Technologies; Jonathan Marsh, Microsoft; Alex Milowski, Lexica; Steve Muench, Oracle; Scott Parnell, Xerox; Vincent Quint, W3C; Dan Rapp, Novell; Gregg Reynolds, Datalogics; Jonathan Robie, Software AG; Mark Scardina, Oracle; Henry Thompson, University of Edinburgh; Philip Wadler, Bell Labs; Norman Walsh, Arbortext; Sanjiva Weerawarana, IBM; Steve Zilles, Adobe (Co-Chair)

F Изменения, Сделанные После Появления Предлагаемых Рекомендаций (ненормативное)

Далее идут изменения, сделанные после появления Proposed Recommendation:

G Возможности, Предусматриваемые в Будущих Версиях XSLT (ненормативное)

Следующие возможности предусматриваются для версий XSLT после XSLT 1.0: