Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

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

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

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

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

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

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

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

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

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

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

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

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

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

то вместо

<xsl:apply-templates/>

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

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

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

7.6 Вычисление подставляемого текста

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

7.6.1 Создание текста с помощью xsl:value-of

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

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

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

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

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

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

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

</xsl:template>

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

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

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

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

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

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

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

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

Из исходного кода

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

будет получено

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

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

В выражении фигурные скобки рекурсивно не обрабатываются. Например, использовать:

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

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

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

7.7 Нумерация

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

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

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

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

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

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

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

Кроме того, атрибуты, описанные в главе [7.7.1 Атрибуты преобразования числа в строку], используются для преобразования числа в строку, как и в случае когда указан атрибут 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.

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

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

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

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

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

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

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

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

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

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

Главным атрибутом является 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 в [XML]. Если значение lang не было указано, язык следует определить из системного окружения. Разработчикам процессоров следует документировать, для каких языков поддерживается нумерация.

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

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

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

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

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

  • format="&#x30A2;" задает нумерацию Katakana

  • format="&#x30A4;" задает нумерацию Katakana в последовательности "iroha"

  • format="&#x0E51;" задает нумерацию тайскими цифрами

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

  • format="&#x10D0;" letter-value="traditional" задает григорианскую нумерацию

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

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

Назад | Содержание | Вперед

 

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...