Язык преобразований XSL

         

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


XML World Wide Web Consortium. Extensible Markup Language (XML) 1.0. Рекомендации W3C. См. Names XML World Wide Web Consortium. Namespaces in XML. Рекомендации W3C. См.

XPath World Wide Web Consortium. XML Path Language. Рекомендации W3C. См.



A.2 Остальные ссылки


CSS2World Wide Web Consortium. Cascading Style Sheets, level 2 (CSS2). Рекомендации W3C. См. DSSSLМеждународная организация по стандартизации, Международная электротехническая комиссия. ISO/IEC 10179:1996. Document Style Semantics and Specification Language (DSSSL). Международный стандарт. HTMLWorld Wide Web Consortium. HTML 4.0 specification. Рекомендации W3C. См. IANAInternet Assigned Numbers Authority. Character Sets. См. . RFC2278N. Freed, J. Postel. IANA Charset Registration Procedures. IETF RFC 2278. См. . RFC2376E. Whitehead, M. Murata. XML Media Types. IETF RFC 2376. См. . RFC2396T. Berners-Lee, R. Fielding, and L. Masinter. Uniform Resource Identifiers (URI): Generic Syntax. IETF RFC 2396. См. http://www.ietf.org/rfc/rfc2396.txt. UNICODE TR10Unicode Consortium. Unicode Technical Report #10. Unicode Collation Algorithm. Unicode Technical Report. См. http://www.unicode.org/unicode/reports/tr10/index.html. XHTMLWorld Wide Web Consortium. XHTML 1.0: The Extensible HyperText Markup Language. Предложенная рекомендация W3C. См. XPointerWorld Wide Web Consortium. XML Pointer Language (XPointer). Предварительный рабочий документ W3C. См. XML StylesheetWorld Wide Web Consortium. Associating stylesheets with XML documents. Рекомендация W3C. См. XSLWorld Wide Web Consortium. Extensible Stylesheet Language (XSL). Предварительный рабочий документ W3C. См.



Атрибуты преобразования числа в строку


Описанные далее атрибуты используются чтобы контролировать преобразование набора чисел в строку. Числа являются целыми и больше нуля. Все атрибуты являются необязательными.

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

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

Любая лексема, где последний символ имеет значение десятичной цифры 1 (указанное в базе данных по свойствам символов Unicode), а значение Unicode предшествующих символов меньше чем значение Unicode последнего символа, генерирует такое десятичное представление числа, что любое число будет не короче лексемы форматирования.
Так, лексема форматирования 1 генерирует последовательность 1 2 ... 10 11 12 ..., а лексема форматирования 01 дает последовательность 01 02 ... 09 10 11 12 ... 99 100 101.

Лексема форматирования A генерирует последовательность A B C ... Z AA AB AC....

Лексема форматирования a генерирует последовательность a b c ... z aa ab ac....

Лексема форматирования i генерирует последовательность i ii iii iv v vi vii viii ix x ....

Лексема форматирования I генерирует последовательность I II III IV V VI VII VIII IX X ....

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



Если нумерация выполняется последовательностью букв, атрибут lang указывает, алфавит какого языка следует использовать. Атрибут имеет тот же самый диапазон значений, что и xml:lang в . Если значение 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, он игнорируется.

Некоторые примеры спецификаций преобразования:

format="ア" задает нумерацию Katakana

format="イ" задает нумерацию Katakana в последовательности "iroha"

format="๑" задает нумерацию тайскими цифрами

format="א" letter-value="traditional" задает "традиционную" еврейскую нумерацию

format="ა" letter-value="traditional" задает григорианскую нумерацию

format="α" letter-value="traditional" задает "классическую" греческую нумерацию

format="а" letter-value="traditional" задает старославянскую нумерацию




B Справочник синтаксиса элементов


<!-- Category: instruction -->

</>

<!-- Category: instruction -->

<

  select = node-set-expression

  mode = qname>

  <!-- Content: ( | )* -->

</xsl:apply-templates>

<!-- Category: instruction -->

<

  name = { qname }
  namespace = { uri-reference }>

  <!-- Content: template -->

</xsl:attribute>

<!-- Category: top-level-element -->

<

  name = qname

  use-attribute-sets = qnames>

  <!-- Content: * -->

</xsl:attribute-set>

<!-- Category: instruction -->

<

  name = qname>

  <!-- Content: * -->

</xsl:call-template>

<!-- Category: instruction -->

<>

  <!-- Content: (+, ?) -->

</xsl:choose>

<!-- Category: instruction -->

<>

  <!-- Content: template -->

</xsl:comment>

<!-- Category: instruction -->

<

  use-attribute-sets = qnames>

  <!-- Content: template -->

</xsl:copy>

<!-- Category: instruction -->

<

  select = expression />

<!-- Category: top-level-element -->

<

  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 -->

<

  name = { qname }

  namespace = { uri-reference }

  use-attribute-sets = qnames>

  <!-- Content: template -->

</xsl:element>

<!-- Category: instruction -->

<>

  <!-- Content: template -->

</xsl:fallback>

<!-- Category: instruction -->



<

  select = node-set-expression>

  <!-- Content: (xsl:sort*, template) -->

</xsl:for-each>

<!-- Category: instruction -->

<

  test = boolean-expression>

  <!-- Content: template -->

</xsl:if>

<

  href = uri-reference />

<!-- Category: top-level-element -->

<

  href = uri-reference />

<!-- Category: top-level-element -->

<

  name = qname

  match = pattern

  use = expression />

<!-- Category: instruction -->

<

  terminate = "yes" | "no">

  <!-- Content: template -->

</xsl:message>

<!-- Category: top-level-element -->

<

  stylesheet-prefix = prefix | "#default"

  result-prefix = prefix | "#default" />

<!-- Category: instruction -->

<

  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 } />

<>

  <!-- Content: template -->

</xsl:otherwise>

<!-- Category: top-level-element -->

<

  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 -->

<

  name = qname

  select = expression>

  <!-- Content: template -->

</xsl:param>

<!-- Category: top-level-element -->

<

  elements = tokens />

<!-- Category: instruction -->

<

  name = { ncname }>

  <!-- Content: template -->

</xsl:processing-instruction>

<

  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 -->

<

  elements = tokens />

<

  id = id

  extension-element-prefixes = tokens

  exclude-result-prefixes = tokens

  version = number>

  <!-- Content: (*, top-level-elements) -->

</xsl:stylesheet>

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

<!-- Category: instruction -->

<

  disable-output-escaping = "yes" | "no">

  <!-- Content: #PCDATA -->

</xsl:text>

<

  id = id

  extension-element-prefixes = tokens

  exclude-result-prefixes = tokens

  version = number>

  <!-- Content: (*, top-level-elements) -->

</xsl:transform>

<!-- Category: instruction -->

<xsl:value-of

  select = string-expression

  disable-output-escaping = "yes" | "no" />

<!-- Category: top-level-element -->

<!-- Category: instruction -->

<

  name = qname

  select = expression>

  <!-- Content: template -->

</xsl:variable>

<

  test = boolean-expression>

  <!-- Content: template -->

</xsl:when>

<

  name = qname

  select = expression>

  <!-- Content: template -->

</xsl:with-param>


Базовый URI


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



C Фрагмент DTD для стилей XSLT (пояснения к спецификации)


Замечание: Данный фрагмент DTD не является нормативным, поскольку в XML 1.0 DTD не поддерживают пространства имен XML, а потому не могут корректно описывать структуру, допустимую для стиля XSLT.

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

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

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

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

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

<!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;)* ">


Замечание: Данный фрагмент DTD не является нормативным, поскольку в XML 1.0 DTD не поддерживают пространства имен XML, а потому не могут корректно описывать структуру, допустимую для стиля XSLT.

Приводимая далее сущность может использоваться при создании DTD для XSLT стилей, который создает экземпляры уже конкретного конечного DTD. Прежде чем ссылаться на сущность, стиль DTD должен определить сущность параметра result-elements, дающего перечень разрешенных типов данного конечного элемента. Например, <!ENTITY % result-elements " | fo:inline-sequence | fo:block ">

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

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

Использование префикса xsl: в этом DTD не означает, что стили XSLT обязаны использовать этот префикс. Любой из элементов, декларированных в этом DTD, в дополнение к атрибутам, декларированным в этом же DTD, может иметь атрибуты, имена которых начинаются с xmlns: или равны xmlns. <!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;)* ">

<!-- Used for the type of an attribute value that is a URI reference.--> <!ENTITY % URI "CDATA">

<!-- Used for the type of an attribute value that is a pattern.--> <!ENTITY % pattern "CDATA">

<!-- Used for the type of an attribute value that is an attribute value template.--> <!ENTITY % avt "CDATA">

<!-- Used for the type of an attribute value that is a QName; the prefix gets expanded by the XSLT processor. --> <!ENTITY % qname "NMTOKEN">

<!-- Like qname but a whitespace-separated list of QNames. --> <!ENTITY % qnames "NMTOKENS">

<!-- Used for the type of an attribute value that is an expression.--> <!ENTITY % expr "CDATA">

<!-- Used for the type of an attribute value that consists of a single character.--> <!ENTITY % char "CDATA">

<!-- Used for the type of an attribute value that is a priority. --> <!ENTITY % priority "NMTOKEN"> <!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!-- This may be overridden to customize the set of elements allowed at the top-level. --> <!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; '>

<!-- This entity is defined for use in the ATTLIST declaration for result elements. --> <!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 cannot occur after any other elements or any non-whitespace character -->

<!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;>



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

<!-- Used for the type of an attribute value that is a URI reference.--> <!ENTITY % URI "CDATA">

<!-- Used for the type of an attribute value that is a pattern.--> <!ENTITY % pattern "CDATA">

<!-- Used for the type of an attribute value that is an attribute value template.--> <!ENTITY % avt "CDATA">

<!-- Used for the type of an attribute value that is a QName; the prefix gets expanded by the XSLT processor. --> <!ENTITY % qname "NMTOKEN">

<!-- Like qname but a whitespace-separated list of QNames. --> <!ENTITY % qnames "NMTOKENS">

<!-- Used for the type of an attribute value that is an expression.--> <!ENTITY % expr "CDATA">

<!-- Used for the type of an attribute value that consists of a single character.--> <!ENTITY % char "CDATA">

<!-- Used for the type of an attribute value that is a priority. --> <!ENTITY % priority "NMTOKEN"> <!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!-- This may be overridden to customize the set of elements allowed at the top-level. --> <!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; '>

<!-- This entity is defined for use in the ATTLIST declaration for result elements. --> <!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 cannot occur after any other elements or any non-whitespace character -->

<!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.1 Пример документа


В данном примере представлен стиль для преобразования документа, соответствующего простому DTD, в 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>

Далее приводится стиль, который, используя упрощенный синтаксис, описанный в главе , преобразует эти данные в формат 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" }


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


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



E Благодарности (пояснения к спецификации)


В разработку предварительного варианта документа вклад внести следующие лица:

Daniel Lipkin, Saba Jonathan Marsh, Microsoft Henry Thompson, Университет Эдинбурга Norman Walsh, Arbortext Steve Zilles, Adobe

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

Sharon Adler, IBM (сопредседатель); 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 (сопредседатель)



F Изменения по внесенным рекомендациям (пояснения к спецификации)


После вынесения предложенной Рекомендации на обсуждение были приняты следующие изменения:

В фиксированном конечном элементе, используемом в качестве стиля, обязательным является атрибут xsl:version (см. ).

Атрибут data-type в xsl:sort может использовать префиксное имя для того, чтобы указывать тип данных, не определенный в XSLT (см. главу ).



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


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

Созданный узел элемента будет также иметь копию узлов для пространства имен, которые присутствовали в узле элемента в дереве стиля, за исключением тех узлов пространства имен, чьим строковым значением является URI пространства имен XSLT (http://www.w3.org/1999/XSL/Transform), URI пространства имен, декларированного как пространство расширения (см. ), или URI пространства имен, обозначенного как исключенное. 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. Поддерево, начинающееся с элемента xsl:stylesheet, не включает стили, импортированные или включенные непосредственным потомком этого элемента xsl:stylesheet.

Замечание: Если стиль использует декларацию пространства имен только для адресации в исходном дереве, то указание этого префикса в атрибуте exclude-result-prefixes позволит избежать появления в конечном дереве ненужных деклараций пространства имен.


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

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

URI пространства имен в расширенном имени фиксированного конечного элемента в этом стиле

URI пространства имен в расширенном имени атрибута, указанного в фиксированном конечном элементе в стиле

строковому значению узла пространства имен в фиксированном конечном элементе в стиле

<!-- Category: top-level-element -->
<xsl:namespace-alias
stylesheet-prefix =

prefix | "#default"
  result-prefix = prefix | "#default" />

Чтобы декларировать, что один URI пространства имен является синонимом другого URI пространства имен, в стиле может использоваться элемент xsl:namespace-alias. Если был декларирован как синоним другого 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 будут неправильно обрабатываться программами обеспечения безопасности общего назначения. Используя синоним для этого пространства имен, такую нестыковку можно устранить.


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


Для стилей, состоящих из единственного шаблона, для корневого узла можно использовать упрощенный синтаксис. Данный стиль может содержать только один фиксированный конечный элемент (literal result element, см. главу ). Такой стиль равнозначен стилю с элементом 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, значение должно иметь тип . Другие фиксированные конечные элементы также должны иметь атрибут xsl:version. Если атрибут xsl:version не равен 1.0, должен быть разрешен режим обработки, совместимый с последующими версиями. (см. главу ).

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

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

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

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



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


Функция: строка format-number(число, строка, строка?)

Функция преобразует свой первый аргумент в строку, используя строку шаблона форматирования, представленную во втором аргументе, и десятичный формат, поименованый в третьем аргументе, либо десятичный формат по умолчанию, если третий аргумент отсутствует. Строка с шаблоном форматирования имеет синтаксис, определенный в JDK 1.1 для класса . Строка шаблона форматирования представлена в локализованной нотации: десятичный формат определяет, какие именно символы в шаблоне имеют специальное значение (за исключением символа кавычки, который не подлежит локализации). Шаблон формата не должен содержать символ денежной единицы (#x00A4), такая возможность была добавлена уже после первой реализации JDK 1.1. Названием десятичного формата должно быть , которое приводится к расширенному имени как описано в главе . Если в стиле отсутствует декларация десятичного формата с заданным , фиксируется ошибка.

Замечание: Разработчики не обязаны использовать именно реализацию 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 декларирует десятичный формат, который управляет интерпретацией шаблона формата, используемого в функции . Если присутствует атрибут name, данный элемент декларирует именованный десятичный формат. В остальных случаях декларируется десятичный формат по умолчанию. Значением атрибута name является , которое приводится к расширенному имени как было описано в главе .
Если десятичный формат по умолчанию или десятичный формат с данным именем, декларируется несколько раз, фиксируется ошибка (даже при различном ). Это можно делать только если каждый раз для всех атрибутов декларированы одни и те же значения (принимая во внимание все значения по умолчанию).

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

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

decimal-separator задает символ, используемый как десятичная точка, по умолчанию используется символ точки (.)

grouping-separator задает символ, используемый как разделитель при группировке (например, тысяч), по умолчанию используется символ запятой (,)

percent задает символ, используемый как символ процента, по умолчанию используется символ процента (%)

per-mille задает символ, используемый как символ промилле, по умолчанию используется символ промилле из набора Unicode (#x2030)

zero-digit задает символ, используемый как цифра нуль, по умолчанию используется цифра нуль (0)



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

digit задает символ, используемый в шаблоне формата для обозначения цифр, по умолчанию таковым является символ решетки (#)

pattern-separator задает символ, используемый для разделения положительной и отрицательной частей в шаблоне, по умолчанию используется символ точки с запятой (;)



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

infinity задает строку, используемую для обозначения бесконечности, по умолчанию используется строка Infinity

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

minus-sign задает символ, используемый по умолчанию как знак "минус", по умолчанию используется символ тире-минус (-, #x2D)




Фрагменты конечного дерева


Переменные привносят в язык выражений новый тип данных. Этот дополнительный тип данных называется фрагментом конечного дерева (result tree fragment). Переменная может быть привязана к фрагменту конечного дерева, а не только к одному из четырех базовых типов данных в XPath (строка, число, булево значение, набор узлов). Фрагмент конечного дерева представляет здесь именно фрагмент в конечном дереве. Фрагмент конечного дерева обрабатывается точно так же как набор узлов, который содержит только один корневой узел. Однако для фрагмента конечного дерева разрешена лишь часть операций, допустимых для набора узлов. Операцию можно использовать для фрагмента конечного дерева только когда ее можно использовать для строки (операция над строкой может включать предварительное преобразование этой строки в число или булево значение). В частности, для фрагментов конечного дерева нельзя использовать операции /, // и []. Если для фрагмента конечного дерева выполняется рпазрешенная операция, то она выполняется точно так же как если применена к эквивалентному набору узлов.

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

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



Функции расширения


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

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

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



Язык преобразований XSL


Для версий XSLT, которые последуют за XSLT 1.0, рассматривается следующий функционал:

выражение при условии;

поддержка типов данных и архитипов для XML Schema;

поддержка чего-либо похожего на правила типов в исходном представлении XSL;

атрибут, задающий пространство имен по умолчанию для имен, используемых в атрибутах XSLT;

поддержка ссылок на сущности;

поддержка DTD в модели данных;

поддержка нотаций в модели данных;

способ обратиться в обратном направлении от элемента к тем элементам, которые на него ссылаются (например, с помощью атрибутов IDREF);

упрощенный способ получить ID или ключ в другом документе;

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

независимое от регистра сравнение;

нормализация строк перед сравнением, например, для совместимости символов;

функция строка resolve(набор узлов), которая обрабатывает значение аргумента как относительный URI и преобразует его в абсолютный URI, используя базовый URI данного узла;

несколько конечных документов;

используемый по умолчанию атрибут select для xsl:value-of в текущем узле;

атрибут в xsl:attribute, позволяющий управлять нормализацией значения этого атрибута;

дополнительные атрибуты в xsl:sort чтобы получить больший контроль над сортировкой, например, над относительным порядком скриптов;

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

позволить объединение шагов (например, foo/(bar|baz));

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

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

свойства, которые бы сделали обработку атрибута HTML style более удобной.



H Словарь (пояснения к спецификации)


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

attribute value template - именованный набор атрибутов

child - непосредственный потомок

conditional processing - обработка при условии

conformance - соответствие спецификации

context node - узел контекста

context node list - контекстный набор узлов

context position - положение в контексте

document element - элемент документа

document type declaration - декларация типа документа, DTD

DTD subset - набор DTD (внутренний, внешний)

element node - узел элемента

escape character - маскировать символ

expanded name - расширенное имя

extension namespace - пространство имен расширений

fallback - откат

forward-compatible processing - обработка в режиме совместимости с последующими версиями

literal result element - фиксированный конечный элемент

location path - путь адресации

named attribute set - именованный набор атрибутов

node set - набор узлов

parsed entity - разобранная сущность

pattern - образец (правила шаблона)

processing instruction - инструкция обработки

production - сценарий (языков XML, XPath)

qualified name - полное имя

result tree - конечное дерево (результат выполнения преобразования)

source tree - начальное дерево (объект преобразования)

standalone document - одиночный документ

stylesheet - стиль оформления

template rule - правило шаблона

top-level element - элемент верхнего уровня

unparsed entity - неразобранная сущность

value-binding element - элемент привязки переменной

variable binding - привязка переменной контекста

vocabulary - словарь форматирования

well-formed - корректный

whitespace - пробельный символ

Если у вас возникли какие-либо замечания, мы будем рады их получить по адресу .



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


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

qnames>
  <!-- Content: xsl:attribute* -->
</xsl:attribute-set>

Элемент xsl:attribute-set определяет именованный набор атрибутов. Название для этого набора атрибутов определяется атрибутом name. Значением атрибута name является , которое приводится к расширенному имени как описано в главе . Содержимое элемента xsl:attribute-set состоит из нуля или нескольких элементов xsl:attribute, которые определяют атрибуты в этом наборе.

Чтобы использовать набор атрибутов в элементах xsl:element, xsl:copy (см. ) или xsl:attribute-set, задается атрибут use-attribute-sets. Значением атрибута use-attribute-sets является перечень названий наборов атрибутов через пробел. Каждое название указывается как , которое приводится к расширенному имени как было описано в . Указание атрибута 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. Поскольку добавление атрибута к элементу замещает любой из уже имевшихся в этом элементе атрибутов c тем же самым названием, это означает, что атрибуты, заданные в наборах атрибутов, могут быть переопределены атрибутами, указанными в самом фиксированном конечном элементе.

Шаблон в каждом элементе xsl:attribute из элемента xsl:attribute-set обрабатывается при каждом использовании данного набора атрибутов. При обработке используются те же самые текущий узел и текущий набор узлов, что и для обработки элемента, содержащего атрибут use-attribute-sets или xsl:use-attribute-sets. Однако у элемента xsl:attribute иное местоположение в стиле, чем у элемента, имеющего атрибут use-attribute-sets или xsl:use-attribute-sets, а это определяет, какие привязки переменных контекста будут видимы (см. ). Таким образом, видимы будут лишь переменные и параметры, декларированные элементами 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>

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


Именованные шаблоны


<!-- Category: instruction -->
<xsl:call-template
name = qname>
  <!-- Content:

href="#element-with-param">xsl:with-param* -->
</xsl:call-template>

Шаблоны можно вызывать по имени. Именованный шаблон задается элементом xsl:template с атрибутом name. Значением атрибута является имя name , которое приводится к расширенному имени как описано в главе . Если элемент 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.

Если стиль содержит более одного шаблона с одним и тем же названием, а также одним и тем же , фиксируется ошибка.



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


<xsl:import
  href = uri-reference />

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

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

Например,

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

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

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

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

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

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



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

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

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

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

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


Использование правил шаблона


<!-- 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 обрабатывает все непосредственные потомки текущего узла, включая узлы текста. Однако те текстовые узлы, которые были вычищены как описано в главе , обрабатываться не будут. Если очистка узлов с пробельными символами для элемента не была разрешена, то все пробельные символы в содержимом этого элемента будут обрабатываться как текст, и, следовательно, пробельный символ между элементами - непосредственными потомками будет учитываться при вычислении положения элемента - непосредственного потомка, возвращаемого функцией .

Чтобы обрабатывать не все непосредственные потомки, а лишь узлы, отобранные по некому выражению, может использоваться атрибут select. Значением атрибута select является . После обработки этого выражения должен получиться набор узлов. Если нет указаний по сортировке (см. ), собранный перечень узлов обрабатывается в том порядке, как они следуют в документе. В следующем примере обрабатываются все непосредственные потомки author для этого элемента author-group:

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

В следующем примере обрабатываются все содержащиеся в author элементы given-name, которые являются непосредственным потомком 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. Сперва находится отдел 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. Первая таблица заполняется отечественными продажами, вторая - международными.

<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.

Замечание: Обычно xsl:apply-templates используется для обработки только тех узлов, которые являются потомками текущего узла. Такое использование xsl:apply-templates не может привести к появлению бесконечных циклов обработки.Однако когда xsl:apply-templates используется для обработки элементов, не являющихся потомками текущего узла, появляется вероятность возникновения бесконечных циклов. Например, <xsl:template match="foo"> <xsl:apply-templates select="."/> </xsl:template> Реализации процессора в некоторых случаях могут выявить такие циклы, однако остается вероятность, что стиль попадет в такой бесконечный цикл, который эта реализация не сможет обнаружить. Для безопасности это может представлять угрозу типа "отказ в обслуживании".


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


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

Чтобы вставить фрагмент конечного дерева в конечное дерево без предварительного преобразования в строку, как это делает xsl:value-of (см. ), можно использовать элемент xsl:copy-of. Обязательный атрибут select содержит . Если результатом обработки выражения является фрагмент конечного дерева, то этот фрагмент целиком копируется в конечное дерево. Если же результатом является набор узлов, в конечное дерево копируются все узлы этого набора и в том порядке, как они были в документе. Когда копируется узел элемента, вместе с самим узлом элемента копируются также узлы атрибутов, узлы пространства имен и непосредственные потомки этого узла элемента. Копирование корневого узла выполняется копированием его непосредственных потомков. Если результат не является ни набором узлов, ни фрагментом конечного дерева, то он преобразуется в строку, а затем помещается в конечное дерево, как при использовании xsl:value-of.



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


<xsl:stylesheet

id = id
  extension-element-prefixes = tokens

  exclude-result-prefixes = tokens

  version = number>

  <!-- Content: (*, top-level-elements) -->

</xsl:stylesheet>

<xsl:transform

  id = id

  extension-element-prefixes = tokens

  exclude-result-prefixes = tokens

  version = number>

  <!-- Content: (*, top-level-elements) -->

</xsl:transform>

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

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

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

xsl:import

xsl:include

xsl:strip-space

xsl:preserve-space

xsl:output

xsl:key

xsl:decimal-format

xsl:namespace-alias

xsl:attribute-set

xsl:variable

xsl:param

xsl:template

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

</xsl:stylesheet>

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

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

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

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

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

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

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


Элементы расширения


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

Замечание: Поскольку элемент, являющийся непосредственным потомком элемента 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, не включает каких-либо стилей, импортированных или включенных непосредственными потомками этого элемента xsl:stylesheet.

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

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



Ключи


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

Атрибуты ID должны быть декларированы в качестве таковых в DTD. Если атрибут ID декларирован в качестве такового лишь во внешнем наборе DTD, то и распознаваться как ID атрибут он будет только тогда, когда процессор XML прочтет этот внешний набор DTD. Однако спецификация XML вовсе не обязует XML процессоры читать этот внешний DTD, а потому процессоры вполне могут этого не делать, особенно если для документа было декларировано standalone="yes".

Документ может иметь только один набор уникальных ID. Не может быть несколько независимых наборов уникальных атрибутов ID.

ID элемента может быть задано лишь в атрибуте. Он не может быть задан ни содержимым элемента, ни элементом, являющимся непосредственным потомком.

ID должен быть именем XML. Например, он не может содержать пробелов.

Элемент может содержать не более одного ID.

Любой конкретный ID может принадлежать только одному элементу.

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

Ключ определяется тремя параметрами:

узлом, которому принадлежит этот ключ

названием ключа ()

значением ключа (строка)

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

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

Ключи декларируются в стиле с помощью элементов xsl:key.

Ключи имеют как название, так и значение. Каждое название ключа можно рассматривать как отдельное, независимое пространство идентификаторов.


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

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

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

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

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

Чтобы декларировать ключи, используется элемент xsl:key. Название создаваемого ключа задает атрибут name. Значением атрибута name является , которое приводится к расширенному имени как было описано в главе . Атрибут match является . Элемент xsl:key дает информацию о ключах во всех узлах, которые соответствуют шаблону, заданному атрибутом match. Атрибут use дает , определяющее значение ключа. Для каждого узла, соответствующего шаблону, это выражение вычисляется отдельно. Если результатом вычисления является набор узлов, то для каждого узла в этом наборе считается, что узлы, соответствующие представленному шаблону, имеют ключ с указанным именем, значением которого является строковое значение данного узла из набора. В противном случае, результат вычисления преобразуется в строку, и соответствующий шаблону узел получает ключ с указанным названием и значением, соответствующим этой строке. Таким образом, узел x имеет ключ с названием y и значением z тогда и только тогда, когда имеется элемент xsl:key, такой что:

x соответствует шаблону, указанному в атрибуте match данного элемента xsl:key,

атрибут name элемента xsl:key имеет значение, равное y, и

если выражение, заданное атрибутом use элемента xsl:key, обрабатывается с текущим узлом x, а в качестве текущего набора узлов используется список, состоящий из одного x, и при этом результатом является объект u, то либо z равно результату преобразования объекта u в строку (как при вызове функции ), либо u - это набор узлов, а z равно строковому значению одного или нескольких узлов из набора u.



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

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

Функция: набор-узлов key(строка, объект)

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

Например, дана декларация

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

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

<!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>Function: </b> ... </a></p> </xsl:template>

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


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


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

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



Копирование


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

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

Элемент xsl:copy может иметь атрибут use-attribute-sets (см. ). Последний используется только при копировании узлов элементов.

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

Например, тождественное преобразование может быть записано с помощью xsl:copy следующим образом:

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

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

Следующий пример показывает как атрибуты 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:apply-templates/>

можно легко сделать

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

если необходимо скопировать атрибут xml:lang.



Метод вывода 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 .

Метод вывода html не должен представлять элемент, иначе чем метод xml, если расширенное имя этого элемента имеет ненулевой URI пространства имен. Элемент, чье расширенное имя имеет ненулевой URI пространства имен, должен быть представлен как XML. Если расширенное имя элемента имеет нулевой URI пространства имен, но локальная часть этого имени как название элемента HTML не распознается, этот элемент должен быть представлен как непустой встроенный элемент, такой как 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 не должен выполнять маскирование содержимого элементов script и style. Например, фиксированный конечный элемент, записанный в стиле как

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

или

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

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

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

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


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

В значении атрибутов URI метод вывода html должен маскировать символы, не относящиеся к набору ASCII, используя метод, рекомендованный в главе Рекомендации HTML 4.0.

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

Инструкции обработки метод вывода html должен завершать символом >, а не комбинацией ?>.

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

<OPTION selected="selected">

должен быть представлен в виде

<OPTION selected>

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

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

должен быть представлен в виде

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

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

<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, за которым следует указанный публичный идентификатор. Если дополнительно указан атрибут doctype-system, то перед публичным идентификатором должен быть показан указанный системный идентификатор. Если указан атрибут doctype-system, но не было атрибута doctype-public, метод вывода должен представить SYSTEM, за которым следует указанный системный идентификатор.

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


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


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

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

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



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


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

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

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

В двух деревьях может отличаться порядок следования атрибутов.

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

Замечание: В ходе вывода конечного дерева как XML XSLT процессору может потребоваться добавить декларации пространства имен.

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

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


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

Если атрибут indent имеет значение yes, то метод вывода xml в дополнение к пробельным символам в конечном дереве может показывать собственные пробельные символы (возможно потому, что пробельные символы будут удалены из исходного документа или из стиля) с тем, чтобы получить более красивый результат. Если атрибут indent имеет значение no, какие-либо дополнительные пробельные символы появляться не должны. Значением атрибута по умолчанию является no. Для размещения дополнительных пробельных символов метод вывода xml должен использовать такой алгоритм, который гарантирует, что когда пробельные символы изъяты из вывода с помощью процедуры, описанной в главе , а список элементов, сохраняющих пробельные символы, ограничивается лишь xsl:text, результат будет таким же, как если дополнительные пробельные символы не использовались.

Замечание: Для тех типов документов, которые содержат элементы со смешанным содержимым, использовать indent="yes" обычно небезопасно.



Атрибут cdata-section-elements содержит список (разделенных пробельными символами). Каждый приводится к расширенному имени с помощью деклараций пространства имен, в области действия которых находится элемент xsl:output с данным . Если имеется пространство имен по умолчанию, то оно используется для тех , которые своего префикса не имеют. Расширение выполняется до того, как несколько элементов xsl:output будут объединены в один эффективный элемент xsl:output. Если членом данного переченя является расширенное имя родителя текстового узла, то сам текстовый узел должен быть представлен в виде блока CDATA. Например,

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

приведет к тому, что фиксированный конечный элемент, записанный в стиле как

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

или

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

будет представлен как

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

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

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

будет представлен в виде

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

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

Блоки CDATA не должны использоваться за исключением тех текстовых узлов, где атрибут cdata-section-elements явно требует вывода с помощью блоков CDATA.

Метод вывода xml должен предоставить декларацию XML, если атрибут omit-xml-declaration не имеет значения yes. Декларация XML должна содержать и информацию о версии, и декларацию кодировки.


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

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

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


Множественные исходные документы


Функция: набор-узлов document(объект, набор-узлов?)

Функция позволяет получить доступ к иным XML-документам помимо основного исходного документа.

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

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

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

Идентификатор фрагмента определяет нечто, чего нельзя представить в виде набора узлов XSLT (например, диапазон символов в текстовом узле).

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

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

Замечание: Поскольку для верхнего уровня нет типа среды xml, данные с иным типом среды, чем text/xml или application/xml действительно могут быть XML.

Ссылка URI может быть относительной. Из набора узлов, представленного во втором аргументе, берется узел, который первым встретится в документе, и его базовый URI (см. ) используется для преобразования относительных URI в абсолютные. Если второй аргумент опущен, то по умолчанию используется тот узел из стиля, который содержит выражение, включающее рассматриваемый вызов функции . Заметим, что ссылка URI нулевой длины является ссылкой на документ, относительно которого эта ссылка URI разрешается. Таким образом, document("") ссылается на корневой узел данного стиля, а представление стиля в виде дерева в точности такое же как если бы в качестве исходного документа был взят XML документ, изначально содержащий этот стиль.

Если два документа идентифицируются одним и тем же URI, то они обрабатываются как один и тот же документ.


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

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

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


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


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

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



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


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

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



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


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



Нотация


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

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

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

Если элемент может быть не пустым, то этот элемент содержит комментарий, описывающий разрешенное содержимое. Разрешенное содержимое задается точно так же, как декларация типа элемента в XML. Запись template означает, что можно использовать любое сочетание текстовых узлов, фиксированных конечных элементов, элементов расширения и XSLT элементов из категории instruction. Запись top-level-elements означает, что можно использовать любое сочетание XSLT элементов из категории top-level-element.

Элементу предшествуют комментарии, указывающие, принадлежит ли он категории instruction, категории top-level-element или обеим. Категория элемента влияниет лишь на то, можно ли его использовать в содержимом элементов, допускающих template или top-level-elements.



Нумерация


<!-- 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 содержит , которое обрабатывается, а полученный объект преобразуется в число, как при вызове функции . Затем это число округляется до целого и преобразуется в строку с помощью атрибутов, описанных в . В данном контексте значение каждого из этих атрибутов интерпретируется как . После преобразования полученная строка подставляется в конечное дерево. Например, в следующем примере требуется отсортированный набор чисел:

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

Атрибут level определяет, какие уровни исходного дерева следует рассматривать. Он имеет значения single, multiple или any. По умолчанию используется single.

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


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

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

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

Если задано level="single", на оси ancesor-or-self берется первый узел, соответствующий образцу count, и строится список длиною единица, содержащий один плюс число узлов, которые соответствуют образцу count, предшествующих данному предку и имеют с ним общего родителя. Если такого предка нет, создается пустой список. Если указан атрибут from, то ищутся лишь те предки, которые являются потомками ближайшего предка, соответствующего образцу from. В этом случае предшествующие узлы, имеющие общего родителя, те же самые как при использовании оси preceding-sibling.

Если указано level="multiple", то создается перечень всех предков текущего узла в том порядке, как они встречаются в документе, а список завершает сам этот элемент. Затем из этого перечня выбираются узлы соответствующие образцу count. И, наконец, каждый узел в этом списке замещается единицей плюс количество предшествующих узлов, имеющих того же родителя и соответствующих образцу count. Если указан атрибут from, то ищутся лишь те предки, которые являются потомками ближайшего предка, соответствующего образцу from. Предшествующие узлы, имеющие того же родителя - те же самые как при использовании оси preceding-sibling.

Если указано level="any", то создается список единичной длины, содержащий количество узлов, которые соответствуют образцу count и принадлежат набору из текущего узла и всех узлов на всех уровнях документа, предшествующих в документе текущему узлу, за исключением всех узлов атрибутов и пространства имен (иными словами, объединенному множеству членов на осях preceding и ancestor-or-self). Если указан атрибут from, то после первого узла рассматриваются только те узлы, предшествующие текущему узлу, которые соответствуют образцу from.



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

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

<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>

Следующий пример последовательно нумерует примечания в главе:

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

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

<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>


Обработка с условием


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



Обработка с условием 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, который задает некое . Содержимое элементов xsl:when и xsl:otherwise является шаблоном. Если обрабатывается элемент xsl:choose, поочередно проверяются все элементы xsl:when. При этом обрабатывается соответствующее выражение, а полученный объект преобразуется в булевый тип как при вызове функции . Обрабатывается содержимое первого, и только первого элемента 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>



Обработка с условием xsl:if


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

Элемент xsl:if имеет атрибут test, который определяет некое . Содержимое элемента является шаблоном. Указанное выражение обрабатывается, а полученный объект преобразуется в булево значение как при вызове функции . Если результатом является 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>



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


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

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

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

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

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

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

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

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


Замечание: Если стиль опосредованно зависит от элемента верхнего уровня, объявленного в XSL более старшей версии чем 1.0, то тогда в этом стиле можно использовать элемент xsl:message с атрибутом terminate="yes" (см. ) чтобы гарантировать, что XSLT процессоры, реализующие более ранние версии XSL, не будут втихую игнорировать указанный элемент верхнего уровня. Например, <xsl:stylesheet version="1.5" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

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

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

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

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

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




Образцы


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

Некоторые примеры шаблонов:

para соответствует любому элементу para

* соответствует любому элементу

chapter|appendix соответствует любому элементу chapter и любому элементу appendix

olist/item соответствует любому элементу item с родителем olist

appendix//para соответствует любому элементу para, предком которого является элемент appendix

/ соответствует корневому узлу

text() соответствует любому текстовому узлу

processing-instruction() соответствует любой инструкции обработки

node() соответствует любому узлу за исключением узла атрибута и корневого узла

id("W11") соответствует элементу с уникальным ID W11

para[1] соответствует любому элементу para, который для своего родителя будет первым непосредственным потомком являющимся элементом para

*[position()=1 and self::para] соответствует любому элементу para, являющемуся для своего родителя первым непосредственным элементом-потомком

para[last()=1] соответствует любому элементу para, который является для своего родителя единственным непосредственным потомком para

items/item[position()>1] соответствует любому элементу item, который имеет родителя items, но не является для этого родителя первым непосредственным потомком item


item[position() mod 2 = 1] будет иметь значение true для любого элемента item, который является нечетным непосредственным потомком item своего родителя.

div[@class="appendix"]//p соответствует любому элементу p, предком которого является элемент div, имеющий атрибут class со значением appendix

@class соответствует любому атрибуту class (но не любому элементу, имеющему атрибут class)

@* соответствует любому атрибуту



Образец должен отвечать грамматике . представляет собой набор образцов для путей адресации, разделенных символом |. Образец для пути адресации - это некий путь адресации, на всех шагах которого используются лишь оси child или attribute. Хотя образцы и не должны использовать ось descendant-or-self, в образцах могут использоваться как оператор //, так и оператор /. Образцы путей адресации могут начинаться также с вызова функций или с фиксированным аргументом. В предикатах образца могут использоваться произвольные выражения так это происходит в предикатах пути адресации.