Выбрать главу

</xsclass="underline" stylesheet>

Результатом этого преобразования будет документ, состоящий из одного пустого элемента html:

<html/>

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

<xsclass="underline" stylesheet

 version="1.0"

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

 <xsclass="underline" template match="/" xmlns="http://www.w3.org/1999/xhtml">

  <xsclass="underline" element name="html"/>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Результатом в этот раз будет элемент с локальной частью имени "html", принадлежащий пространству имен с URI "http://www.w3.org/1999/xhtml":

<html xmlns="http://www.w3.org/1999/xhtml" />

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

Элемент xsclass="underline" attribute

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

<xsclass="underline" attribute

 name="{имя}"

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

 <!-- Содержимое: шаблон -->

</xsclass="underline" attribute>

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

Показаний к применению xsclass="underline" attribute несколько больше, чем для xsclass="underline" element. В частности, xsclass="underline" attribute следует использовать, если:

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

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

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

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

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

<element name="record">

 <attribute name="fieldcount" value="12"/>

 <attribute name="title" value="Aggregation"/>

</element>

в элемент

<record fieldcount="12" title="Aggregation"/>

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

Листинг 7.5. Создание атрибутов при помощи xsclass="underline" attribute

<xsclass="underline" stylesheet

 version="1.0"

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

 <xsclass="underline" template match="element">

  <xsclass="underline" element name="{@name}">

   <xsclass="underline" apply-templates select="attribute"/>

  </xsclass="underline" element>

 </xsclass="underline" template>

 <xsclass="underline" template match="attribute">

  <xsclass="underline" attribute name="{@name}">

   <xsclass="underline" value-of select="@value"/>

  </xsclass="underline" attribute>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

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

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

□ элемента xsclass="underline" element;

□ элемента xsclass="underline" copy в случае, если текущий, копируемый узел является элементом;

□ элемента xsclass="underline" attribute-set в случае определения именованного набора атрибутов.

При этом, как было показано в предыдущем примере, xsclass="underline" attribute не обязан использоваться только в качестве их непосредственного дочернего элемента. Главное, чтобы атрибуты создавались в элементах и только в элементах.

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

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

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

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

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

 <xsclass="underline" attribute name="href">

  <xsclass="underline" text>http://www.bbb.com</xsclass="underline" text>

 </xsclass="underline" attribute>

</a>

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

<a href="http://www.bbb.com"/>

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

Текстовое значение атрибута может задаваться не только символьными данными, Оно может генерироваться также элементами XSLT, такими, как, например, xsclass="underline" text и xsclass="underline" value-of. То есть вполне корректным будет следующее определение:

<xsclass="underline" attribute name="href">

 <xsclass="underline" text>http://</xsclass="underline" text>

 <xsclass="underline" value-of select="concat('www', '.', 'bbb')"/>

 <xsclass="underline" text>.com</xsclass="underline" text>

</xsclass="underline" attribute>

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

<xsclass="underline" attribute name="href">а¶

 b</xsclass="underline" attribute>

создаст атрибут с именем "href" и значением "a&#xA;b":

<а href="a&#xA;b"/>

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

<xsclass="underline" attribute name="href">a□b</xsclass="underline" attribute>

и

<xsclass="underline" attribute name="href">a¶

b</xsclass="underline" attribute>

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