друг!
ЯндексЯндекс. ДеньгиХочу такую же кнопку

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

5.2 Образцы

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

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

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

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

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

Образцы

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

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

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

Хотя семантика образцов формулируется косвенно в терминах обработки выражений, смысл образца легко понять сразу, не прибегая к терминологии обработки выражений. Символ | в образце обозначает альтернативу. Соответствие образцу с одним или несколькими символами |, разделяющими альтернативы, засчитывается если есть соответствие одной из этих альтернатив. Для образца, состоящего из последовательности StepPattern-ов, разделенных / или //, соответствие проверяется справа налево. Соответствие образцу засчитывается только если есть соответствие самому правому StepPattern, а соответствующий элемент отвечает остальной части образца. Если разделителем является /, то таким элементом может быть только родитель, если же разделителем является //, то в качестве такого элемента может использоваться любой из предков. Соответствие StepPattern, использующему ось child, засчитывается если для данного узла NodeTest дает true, а сам узел не является узлом атрибута. Соответствие StepPattern, использующему ось attribute, засчитывается если для данного узла NodeTest дает true, а сам узел является узлом атрибута. Если присутствует [], то в StepPattern сперва обрабатывается PredicateExpr, причем проверяемый узел используется как узел контекста, а в качестве контекстного набора узлов берутся узлы, которые имеют общего родителя с узлом контекста и соответствуют NodeTest. Однако если проверяемый узел является узлом атрибута, то в этом случае контекстный набор узлов - это все атрибуты, имеющие с проверяемым атрибутом общего родителя и соответствующие NameTest. Например,

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

соответствует узлу тогда и только тогда, когда выполняются все следующие условия:

  • NodeTest item дает true для данного узла, а сам узел не является узлом атрибута, иными словами, данный узел является элементом item

  • обработка PredicateExpr position()=1 дает true, если данный узел берется как узел контекста, а набор элементов item, имеющих с ним общего родителя, берется как контекстный набор узлов

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

5.3 Определение правил шаблона

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

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

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

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

<xsl:template match="emph">  

  <fo:inline-sequence font-weight="bold">    

    <xsl:apply-templates/>  

  </fo:inline-sequence>

</xsl:template>

Примечание: В примерах этого документа префикс fo: используется для пространства имен http://www.w3.org/1999/XSL/Format (пространства имен объектов форматирования, определенных в [XSL]).

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

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

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

В данном примере для элемента chapter создается блок, а затем обрабатывается его непосредственный потомок.

<xsl:template match="chapter">  

  <fo:block>    

    <xsl:apply-templates/>  

   </fo:block>

</xsl:template>

В отсутствие атрибута select инструкция xsl:apply-templates обрабатывает все непосредственные потомки текущего узла, включая узлы текста. Однако те текстовые узлы, которые были вычищены как описано в главе [3.4 Удаление пробельных символов], обрабатываться не будут. Если очистка узлов с пробельными символами для элемента не была разрешена, то все пробельные символы в содержимом этого элемента будут обрабатываться как текст, и, следовательно, пробельный символ между элементами - непосредственными потомками будет учитываться при вычислении положения элемента - непосредственного потомка, возвращаемого функцией position. Чтобы обрабатывать не все непосредственные потомки, а лишь узлы, отобранные по некому выражению, может использоваться атрибут select. Значением атрибута select является выражение. После обработки этого выражения должен получиться набор узлов. Если нет указаний по сортировке (см. [10 Сортировка]), собранный перечень узлов обрабатывается в том порядке, как они следуют в документе. В следующем примере обрабатываются все непосредственные потомки 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>

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

5.5 Разрешение конфликтов в правилах шаблона

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

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

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

    • Если образец содержит несколько альтернатив, разделенных символом |, то он обрабатывается также как набор из правил шаблона, по одному на каждую из представленных альтернатив.

    • Если образец имеет вид QName, которому предшествует ChildOrAttributeAxisSpecifier, или имеет вид processing-instruction(Literal), которому предшествует ChildOrAttributeAxisSpecifier, то приоритет считается равным 0.

    • Если образец имеет вид NCName:*, которому предшествует ChildOrAttributeAxisSpecifier, то его приоритет равен -0.25.

    • В противном случае, если образец состоит только из NodeTest, которому предшествует ChildOrAttributeAxisSpecifier, то его приоритет равен -0.5.

    • В остальных случаях приоритет равен 0.5.

    Таким образом, самый общий тип образцов (образец, проверяющий узел определенного типа и с определенным расширенным именем) имеет приоритет 0. Следующий, более общий тип образца (образец, проверяющий узел определенного типа и с расширенным именем и определенным URI пространства имен) имеет приоритет -0.25. Еще более общие образцы (образцы, проверяющие лишь узлы определенных типов) имеют приоритет -0.5. Образцы, еще более специальные, чем самый общий тип образца, имеют приоритет 0.5.

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

5.6 Переопределение правил шаблона

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

Правило шаблона, которое должно использоваться для переопределения другого правила шаблона в импортированном стиле (см. [5.5 Разрешение конфликтов в правилах шаблона]), может воспользоваться элементом xsl:apply-imports чтобы вызвать переопределенное правило шаблона. При обработке стиля в каждой точке имеется некое текущее правило шаблона. Всякий раз, когда по образцу выбирается правило шаблона, для обработки оно становится текущим правилом шаблона. Когда обрабатывается элемент xsl:for-each, то при обработке содержимого этого элемента xsl:for-each текущее правило шаблона становится нулевым. xsl:apply-imports обрабатывает текущий узел используя лишь те правила шаблона, которые были импортированы в тот элемент стиля, где это текущее правило шаблона находится. Узел обрабатывается в режиме текущего правила шаблона. Если xsl:apply-imports обрабатывается когда текущее правило шаблона нулевое, фиксируется ошибка. Например, предположим что стиль doc.xsl содержит правило шаблона для элементов example:

<xsl:template match="example">  

  <pre><xsl:apply-templates/></pre>

</xsl:template>

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

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

<xsl:template match="example">  

  <div >     

    <xsl:apply-imports/>  

  </div>

</xsl:template>

В результате суммарного действия example должен преобразовываться в элемент следующего вида:

<div ><pre>...</pre></div>

5.7 Режимы

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

5.8 Встроенные правила шаблона

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

<xsl:template match="*|/">  

  <xsl:apply-templates/>

</xsl:template>

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

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

   <xsl:apply-templates mode="m"/>

</xsl:template>

Также есть встроенное правило шаблона для текстовых узлов и узлов атрибутов, которое просто копирует текст:

<xsl:template match="text()|@*">  

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

</xsl:template>

Для инструкций обработки и комментариев встроенное правило шаблона не должно делать ничего.

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

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

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

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

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

7 Создание конечного дерева

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

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

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

В шаблоне элемент из стиля, который не принадлежит пространству имен XSLT и не является элементом расширения (см. [14.1 Элементы расширения]), обрабатывается, чтобы создать узел элемента с тем же расширенным именем. Содержимое этого элемента является шаблоном, который обрабатывается чтобы получить содержимое для созданного узла элемента. Узел созданного элемента будет иметь те узлы атрибутов, которые были представлены в дереве стиля в узле данного элемента, а не атрибутов с названиями из пространства имен XSLT. Созданный узел элемента будет также иметь копию узлов для пространства имен, которые присутствовали в узле элемента в дереве стиля, за исключением тех узлов пространства имен, чьим строковым значением является URI пространства имен XSLT (http://www.w3.org/1999/XSL/Transform), URI пространства имен, декларированного как пространство расширения (см. [14.1 Элементы расширения]), или 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 пространства имен, а тем URI пространства имен, для которого он является синонимом. Элемент xsl:namespace-alias декларирует, что URI пространства имен, связанный с префиксом, задаваемым атрибутом stylesheet-prefix, является синонимом для URI пространства имен, связанного с префиксом, задаваемым атрибутом result-prefix. Таким образом, атрибут <stylesheet-prefix указывает URI пространства имен, который будет представлен в стиле, а атрибут result-prefix задает соответствующий URI пространства имен, который будет представлен в конечном дереве. Пространство имен по умолчанию (декларируемое с помощью xmlns) может быть задано не префиксом, а с помощью #default. Если некое URI пространства имен декларировано как синоним сразу для нескольких различных URI пространства имен, то используется декларация с наивысшим приоритетом импорта. Если и таких деклараций будет несколько, фиксируется ошибка. XSLT процессор может сигнализировать об этой ошибке, если он этого не делает, то должен обработать ошибку сам, выбрав среди деклараций с наивысшим приоритетом импорта ту, которая в стиле появилась последней. Если фиксированные конечные элементы используются для создания узлов элементов, атрибутов или пространств имен, использующих URI пространства имен XSLT, такой стиль должен использовать синоним. Например, стиль

<xsl:stylesheet version="1.0"  

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

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

xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">

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

  <xsl:template match="/">  

    <axsl:stylesheet>    

      <xsl:apply-templates/>  

    </axsl:stylesheet>

  </xsl:template>

  <xsl:template match="block">

    <axsl:template match="">

      <fo:block><axsl:apply-templates/></fo:block>

    </axsl:template>

  </xsl:template>

</xsl:stylesheet>

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

<elements>

<block>p</block>

<block>h1</block>

<block>h2</block>

<block>h3</block>

<block>h4</block>

</elements>

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

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

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

Элемент xsl:element позволяет создавать элемент с вычисляемым названием. Расширенное имя создаваемого элемента определяется обязательным атрибутом name и необязательным атрибутом namespace. Содержимое элемента xsl:element является шаблоном для атрибутов и непосредственного потомка создаваемого элемента. Атрибут name интерпретируется как шаблон значения атрибута. Если строка, получающаяся после обработки шаблона значения атрибута, не является QName, фиксируется ошибка. XSLT процессор может сигнализировать об этой ошибке, если он этого не делает, то должен обработать ошибку сам, представив результат обработки элемента xsl:element последовательностью узлов, созданных обработкой содержимого элемента xsl:element и исключением всех исходных узлов атрибутов. Если атрибут namespace не был предоставлен, QName приводится к расширенному имени с помощью деклараций пространства имен, в области действия которых находится данный элемент xsl:element, включая все декларации пространства имен по умолчанию. Если атрибут namespace присутствует, также обрабатывается как шаблон значения атрибута. Строка, полученная после обработки шаблона значения атрибута, должна являться ссылкой URI. Если эта строка не будет синтаксически правильной ссылкой URI, ошибка фиксироваться не будет. Если строка пустая, то расширенное имя данного элемента имеет нулевой URI пространство имен. В противном случае, эта строка используется как URI пространства имен для расширенного имени создаваемого элемента. Локальная часть QName, задаваемая атрибутом name, используется как локальная часть в расширенном имени создаваемого элемента. При отборе префикса для вывода созданного элемента в виде XML XSLT процессоры могут воспользоваться префиксом QName, задаваемым атрибутом name, однако они вовсе не обязаны поступать именно так.

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

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

Чтобы к конечным элементам добавить атрибуты, можно использовать элемент xsl:attribute независимо от того, созданы ли первые фиксированными конечными элементами или такими инструкциями, как xsl:element. Расширенное имя для создаваемого атрибута задается обязательным атрибутом name и необязательным атрибутом namespace. Обработка элемента xsl:attribute добавляет к узлу, содержащему конечный элемент, узел атрибута. Содержимое элемента xsl:attribute является шаблоном для значения создаваемого атрибута. Атрибут name интерпретируется как шаблон значения атрибута. Если строка, возникающая после обработки шаблона значения атрибута, не является QName и не является строкой xmlns, фиксируется ошибка. XSLT процессор может сигнализировать об этой ошибке. Если он этого не делает, то должен сам обработать ошибку, просто не добавляя в конечное дерево этот атрибут. Если атрибут namespace отсутствует, QName приводится к расширенному имени с помощью деклараций пространства имен в области действия которых находится данный элемент xsl:attribute, но без обращения к какой-либо декларации пространства имен по умолчанию. Если имеется атрибут namespace, он тоже интерпретируется как шаблон значения атрибута. Строка, которая получается после его обработки, должна быть ссылкой URI. Однако если эта строка не является синтаксически корректной ссылкой URI, ошибка фиксироваться не будет. Если строка пуста, расширенное имя этого атрибута имеет пустой URI пространства имен. В противном случае, эта строка используется как URI пространства имен для расширенного имени создаваемого атрибута. Локальная часть QName, задаваемая атрибутом name, используется как локальная часть расширенного имени создаваемого атрибута. При выборе префикса для вывода созданного атрибута в виде XML XSLT процессоры могут воспользоваться префиксом QName, указанным в атрибуте name. Однако процессоры не обязаны делать именно так, а если префиксом является xmlns, то им так делать и не разрешается. Таким образом, хотя следующая инструкция ошибки не вызовет

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

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

  • Добавление атрибута к элементу после того как к нему добавлен непосредственный потомок. Реализации процессора могут либо сигнализировать об этой ошибке, либо игнорировать этот атрибут.

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

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

Замечание: Если xsl:attribute содержит текстовый узел с символом перехода на новую строку (newline), то выводимый XML должен содержать ссылку на символ. Например,

<xsl:attribute name="a">x

y</xsl:attribute>

будет давать на выходе

a="x&#xA;y"

(или любую эквивалентную этому ссылку на символ). На выходе XML не может появиться

a="x

y"

Это сделано потому, что XML 1.0 требует, чтобы символы newline в значениях атрибутов были преобразованы в пробелы (нормализованы), тогда как ссылки на символ newline нормализации не подлежат. Значения атрибута в рассматриваемой модели данных представляют собой значение атрибута после нормализации. Если символ newline, появившийся в значении атрибута в дереве, был представлен символом newline, а не ссылкой на символ, то в дереве после повторной обработки XML значение этого атрибута будет содержать уже не newline, а пробел, т.е. такое дерево будет показано неправильно.

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

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

Элемент xsl:attribute-set определяет именованный набор атрибутов. Название для этого набора атрибутов определяется атрибутом name. Значением атрибута name является QName, которое приводится к расширенному имени как описано в главе [2.4 Полные имена]. Содержимое элемента xsl:attribute-set состоит из нуля или нескольких элементов xsl:attribute, которые определяют атрибуты в этом наборе. Чтобы использовать набор атрибутов в элементах xsl:element, xsl:copy (см. [7.5 Копирование]) или xsl:attribute-set, задается атрибут use-attribute-sets. Значением атрибута use-attribute-sets является перечень названий наборов атрибутов через пробел. Каждое название указывается как QName, которое приводится к расширенному имени как было описано в [2.4 Полные имена]. Указание атрибута use-attribute-sets равнозначно добавлению элементов xsl:attribute для каждого атрибута в каждом именованном наборе атрибутов в начало содержимого того элемента, где этот атрибут use-attribute-sets находится, причем в том же порядке как названия этих наборов были перечислены в атрибуте use-attribute-sets. Если в результате использования атрибутов use-attribute-sets в элементах xsl:attribute-set набор атрибутов начинает прямо или косвенно использовать сам себя, фиксируется ошибка. Наборы атрибутов можно также использовать, указывая в фиксированном конечном элементе атрибут xsl:use-attribute-sets. Значением атрибута xsl:use-attribute-sets является перечень названий наборов атрибутов через пробел. Использование атрибута xsl:use-attribute-sets дает тот же результат, как использование атрибута use-attribute-sets в xsl:element с тем дополнительным ограничением, что атрибуты, указанные в фиксированном конечном элементе, сами обрабатываются так, как если бы они были заданы элементами xsl:attribute прежде всех настоящих элементов xsl:attribute, но после всех элементов xsl:attribute, подставляемых атрибутом xsl:use-attribute-sets. Таким образом, для фиксированного конечного элемента первыми будут добавлены атрибуты из наборов, названных в атрибуте xsl:use-attribute-sets, и именно в том порядке, как они были перечислены в этом атрибуте. Затем будут добавлены атрибуты, указанные в фиксированном конечном элементе. И наконец, будут добавлены все атрибуты, заданные элементами xsl:attribute. Поскольку добавление атрибута к элементу замещает любой из уже имевшихся в этом элементе атрибутов c тем же самым названием, это означает, что атрибуты, заданные в наборах атрибутов, могут быть переопределены атрибутами, указанными в самом фиксированном конечном элементе. Шаблон в каждом элементе xsl:attribute из элемента xsl:attribute-set обрабатывается при каждом использовании данного набора атрибутов. При обработке используются те же самые текущий узел и текущий набор узлов, что и для обработки элемента, содержащего атрибут use-attribute-sets или xsl:use-attribute-sets. Однако у элемента xsl:attribute иное местоположение в стиле, чем у элемента, имеющего атрибут use-attribute-sets или xsl:use-attribute-sets, а это определяет, какие привязки переменных контекста будут видимы (см. [11 Переменные и параметры]). Таким образом, видимы будут лишь переменные и параметры, декларированные элементами верхнего уровня 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 процессор может сигнализировать о такой ошибке. Если он этого не делает, то должен обработать ошибку сам, выбирая среди деклараций, определяющих этот атрибут и имеющих наивысший приоритет импорта, ту, которая в стиле была дана последней. Местонахождение в наборе атрибутов имеет значение при объединении атрибутов в данный набор. Когда же набор атрибутов используется, никакой разницы нет.

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

Шаблон также может содержать текстовые узлы. Каждый текстовый узел в шаблоне, оставшийся после удаления пробельных символов, описанного в главе [3.4 Удаление пробельных символов], создаст в конечном дереве текстовый узел с тем же самым строковым значением. Смежные текстовые узлы в конечном дереве автоматически объединяются. Заметим, что текст обрабатывается на уровне дерева. Таким образом, разметка &lt; в шаблоне будет представлена в дереве стиля текстовым узлом, содержащим символ <. В результате в конечном дереве будет создан текстовый узел, содержащий символ <. Если конечное дерево представляется в виде XML документа, последний будет представлен разметкой &lt; или эквивалентной ссылкой на символ (при условии, что маскирование вывода не было блокировано, как описано в [16.4 Запрет маскирования при выводе]).

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

Символы фиксированных данных также могут быть помещены в элемент xsl:text. Такое окружение может отменить режим удаления пробельных символов (см. [3.4 Удаление пробельных символов]), но не влияет на то, как эти символы впоследствии будут обрабатываться XSLT процессором.

Замечание: Атрибуты xml:lang и xml:space не обрабатываются в XSLT как-либо особо. Например,
  • автор стиля непосредственно отвечает за генерацию всех атрибутов xml:lang и xml:space, которые необходимы в результате;

  • появление атрибута xml:lang или xml:space в элементе из пространства имен XSLT не приводит к появлению атрибутов xml:lang или xml:space в конечном материале.

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

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

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

<xsl:processing-instruction name="xml-stylesheet">

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

создаст инструкцию обработки

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

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

Замечание: Это означает что xsl:processing-instruction нельзя использовать для вывода XML декларации. Вместо нее должен использоваться элемент xsl:output (см. [16 Вывод]).

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

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

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

Для создания в конечном дереве узла комментариев используется элемент xsl:comment. Содержимое элемента xsl:comment является шаблоном для строкового значения данного узла комментария. Например,

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

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

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

<< Предыдущая глава | Следующая глава >>

ROL.RU