Мы специально привели все преобразование целиком, чтобы показать, что выходящий элемент будет принадлежать нулевому пространству имен тогда и только тогда, когда для него не было объявлено пространства имен по умолчанию. Попробуем посмотреть, что получится, если пространство имен по умолчанию будет объявлено:
в этот раз будет элемент с локальной частью имени "
html
", принадлежащий пространству имен с URI "
http://www.w3.org/1999/xhtml
":
<html xmlns="http://www.w3.org/1999/xhtml" />
Создание узлов атрибутов
Элемент xsl:attribute
Этот элемент задается конструкцией вида:
<xsl:attribute
name="{имя}"
namespace="{пространство имен}">
<!-- Содержимое: шаблон -->
</xsl:attribute>
Использование элементов
xsl:attribute
и
xsl:element
во многом аналогично. Обязательный атрибут name указывает имя, а атрибут
namespace
— URI пространства имен создаваемого атрибута, причем процесс вычисления расширенного имени атрибута практически идентичен этому в процедуре вычисления имени элемента, который был приведен при разборе
xsl:element
.
Показаний к применению
xsl:attribute
несколько больше, чем для
xsl:element
. В частности,
xsl:attribute
следует использовать, если:
□ требуется создать атрибут с не известным заранее именем или пространством имен;
□ требуется создать атрибут в пространстве имен, которое является для процессора значащим (например, в пространстве имен XSLT);
□ требуется создать атрибут, вычисление значения которого не может быть реализовано одним или несколькими XPath-выражениями (например, условный вывод атрибута).
Приведем некоторые примеры.
Покажем, как преобразовать структуру вида
<element name="record">
<attribute name="fieldcount" value="12"/>
<attribute name="title" value="Aggregation"/>
</element>
в элемент
<record fieldcount="12" title="Aggregation"/>
Для достижения цели воспользуемся следующим преобразованием.
Листинг 7.5. Создание атрибутов при помощи xsl:attribute
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="element">
<xsl:element name="{@name}">
<xsl:apply-templates select="attribute"/>
</xsl:element>
</xsl:template>
<xsl:template match="attribute">
<xsl:attribute name="{@name}">
<xsl:value-of select="@value"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Элемент
xsl:attribute
не может использоваться где угодно: узлы атрибутов должны создаваться только как дочерние узлы узлов элементов. Более того, узлы атрибутов должны создаваться до создания дочерних узлов других типов — текста, элементов и так далее. Таким образом,
xsl:attribute
может быть использован в содержимом любого из следующих родителей:
□ литерального элемента результата;
□ элемента
xsl:element
;
□ элемента
xsl:copy
в случае, если текущий, копируемый узел является элементом;
□ элемента
xsl:attribute-set
в случае определения именованного набора атрибутов.
При этом, как было показано в предыдущем примере,
xsl:attribute
не обязан использоваться только в качестве их непосредственного дочернего элемента. Главное, чтобы атрибуты создавались в элементах и только в элементах.
Элемент
xsl:attribute
также не может использоваться для генерации объявлений пространств имен. В соответствии с технической рекомендацией XSLT,
xsl:attribute
не может создавать атрибуты, имена которых имеют префикс
xmlns
.
Если атрибут создается в элементе, который уже имеет атрибут с таким же именем, старый атрибут будет переопределен новым значением.
Рассмотрим пример.
Листинг 7.6. Фрагмент шаблона
<а href="#">
<xsl:attribute name="href">
<xsl:text>http://www.bbb.com</xsl:text>
</xsl:attribute>
</a>
Листинг 7.7. Результат
<a href="#"/>
Поскольку атрибут может содержать только текст, результатом выполнения содержимого
xsl:attribute
тоже должны быть только текстовые узлы. Процессор в лучшем случае проигнорирует нетекстовые узлы, в худшем выведет сообщение об ошибке, прервав дальнейшую обработку, так что следует очень внимательно относиться к содержимому