Технология XSLT — страница 28 из 66

Элемент xsl:attribute

Этот элемент задается конструкцией вида:

name="{имя}"

 namespace="{пространство имен}">

Использование элементов

xsl:attribute
и
xsl:element
во многом аналогично. Обязательный атрибут name указывает имя, а атрибут
namespace
— URI пространства имен создаваемого атрибута, причем процесс вычисления расширенного имени атрибута практически идентичен этому в процедуре вычисления имени элемента, который был приведен при разборе
xsl:element
.

Показаний к применению

xsl:attribute
несколько больше, чем для
xsl:element
. В частности,
xsl:attribute
следует использовать, если:

□ требуется создать атрибут с не известным заранее именем или пространством имен;

□ требуется создать атрибут в пространстве имен, которое является для процессора значащим (например, в пространстве имен XSLT);

□ требуется создать атрибут, вычисление значения которого не может быть реализовано одним или несколькими XPath-выражениями (например, условный вывод атрибута).

Приведем некоторые примеры.

Покажем, как преобразовать структуру вида

в элемент

Для достижения цели воспользуемся следующим преобразованием.

Листинг 7.5. Создание атрибутов при помощи xsl:attribute

 version="1.0"

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




Элемент

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

□ литерального элемента результата;

□ элемента

xsl:element
;

□ элемента

xsl:copy
в случае, если текущий, копируемый узел является элементом;

□ элемента

xsl:attribute-set
в случае определения именованного набора атрибутов.

При этом, как было показано в предыдущем примере,

xsl:attribute
не обязан использоваться только в качестве их непосредственного дочернего элемента. Главное, чтобы атрибуты создавались в элементах и только в элементах.

Элемент

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

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

Рассмотрим пример.

Листинг 7.6. Фрагмент шаблона

<а href="http://www.aaa.com">

http://www.bbb.com

Листинг 7.7. Результат

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

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

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

xsl:text
и
xsl:value-of
. То есть вполне корректным будет следующее определение:

http://

.com

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

а¶

 b

создаст атрибут с именем "

href
" и значением "
a
b
":

<а href="a
b"/>

Техническая рекомендация объясняет такую ситуацию следующим образом: в соответствии со стандартом языка XML, символы перевода строки должны нормализоваться в значениях атрибутов пробелами, сущности же нормализовать не нужно. Но если бы символ перевода строки нормализовался в XSLT при выводе пробелом, то определения

a□b

и

b

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


или

).

Подводя итог, перечислим в краткой форме основные особенности обращения с

xsl:attribute
.

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

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

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

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

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

Элемент xsl:attribute-set

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

name="имя"

 use-attribute-sets="имена">

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

xsl:attribute-set
. Обязательный атрибут
name
задает имя набора атрибутов. Элемент
xsl:attribute-set
содержит последовательность, состоящую из нуля или более элементов
xsl:attribute
.

Именованные наборы атрибутов можно использовать, указывая их имена в значении атрибута

use-attribute-sets
, который может присутствовать в элементах
xsl:element
,
xsl:copy
и
xsl:attribute-set
, а также в литеральных результирующих элементах. В атрибуте
use-attribute-sets
через пробел перечисляются имена наборов атрибутов, которые должны быть использованы в данном элементе.

Включение набора атрибутов в элемент равносильно простому копированию элементов

xsl:attribute
, определенных в соответствующих элементах
xsl:attribute-set
.

Пример

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

element
, атрибут
name
которых равен имени, атрибут
attr-count
 — количеству атрибутов, а атрибут
node-count
— количеству дочерних узлов соответствующего элемента.

Листинг 7.8. Входящий документ

Листинг 7.9. Преобразование

 version="1.0"

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




   use-attribute-sets="elements attrs">


Листинг 7.10. Выходящий документ

В этом преобразовании определение элемента

 use-attribute-sets="elements attrs">

равносильно определению

Как уже было сказано, элемент

xsl:attribute-set
может также использовать другие наборы атрибутов при помощи
use-attribute-sets
. Например, в предыдущем преобразовании набор атрибутов
elements
мог быть определен как:

 use-attribute-sets="attrs">

Тогда для достижения того же результата элемент с именем

element
мог быть создан с использованием только одного набора атрибутов:

 use-attribute-sets="elements">

Именованный набор атрибутов не может прямо или косвенно (посредством других наборов атрибутов) использовать в значении

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

Атрибут xsl:use-attribute-sets

Мы упомянули о том, что именованные наборы атрибутов используются в элементах посредством атрибута

xsl:use-attribute-sets
. Разберем более детально, где этот атрибут может применяться, и какие функции он при этом выполняет. Для удобства эти данные сведены в табл. 7.1.


Таблица 7.1. Использование атрибута

xsl:use-attribute-sets

Родительский элементОсобенности использования
xsl:attribute-set
Включает в определяемый набор атрибутов атрибуты из перечисленных наборов
xsl:element
Включает в создаваемый элемент атрибуты из перечисленных наборов. Включение эквивалентно текстовому включению — значения атрибутов вычисляются в контексте создающего элемента
xsl:element
xsl:copy
Включает в копируемый элемент атрибуты из перечисленных наборов. Принцип действия— как в случае с
xsl:element
. Копируемый узел должен быть элементом
Литеральный результирующий элементПринцип действия такой же, как и в случае с
xsl:element
. В случае совпадения имен, значения атрибутов из набора будут переопределять значения атрибутов самого элемента. При использовании в литеральном элементе, атрибут
xsl:use-attribute-sets
должен быть обязательным образом объявлен принадлежащим пространству имен XSLT. Как правило, это делается указанием префикса
xsl

Создание текстовых узлов