Именованные наборы атрибутов
Именованные наборы атрибутов
Элемент xsl:attribute-set
Синтаксис элемента определяется следующей конструкцией:
<xsl:attribute-set
name="имя"
use-attribute-sets="имена">
<!-- Содержимое: несколько элементов xsl:attribute -->
</xsl:attribute-set>
Для того чтобы упростить создание в элементах целых наборов атрибутов, можно заранее определить их в элементе 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. Входящий документ
<a b="1" c="2">
<d e="3" f="4" g="5"/>
</a>
Листинг 7.9. Преобразование
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:attribute-set name="attrs">
<xsl:attribute name="attr-count">
<xsl:value-of select="count(@*)"/>
</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="elements">
<xsl:attribute name="name">
<xsl:value-of select="name()"/>
</xsl:attribute>
<xsl:attribute name="node-count">
<xsl:value-of select="count(*)"/>
</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="*">
<xsl:element name="element"
use-attribute-sets="elements attrs">
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Листинг 7.10. Выходящий документ
<?xml version="1.0" encoding="utf-8"?>
<element name="a" node-count="1" attr-count="2">
<element name="d" node-count="0" attr-count="3"/>
</element>
В этом преобразовании определение элемента
<xsl:element name="element"
use-attribute-sets="elements attrs">
<xsl:apply-templates select="*"/>
</xsl:element>
равносильно определению
<xsl:element name="element">
<xsl:attribute name="name">
<xsl:value-of select="name()"/>
</xsl:attribute>
<xsl:attribute name="node-count">
<xsl:value-of select="count(*)"/>
</xsl:attribute>
<xsl:attribute name="attr-count">
<xsl:value-of select="count(@*)"/>
</xsl:attribute>
<xsl:apply-templates select="*"/>
</xsl:element>
Как уже было сказано, элемент xsl:attribute-set может также использовать другие наборы атрибутов при помощи use-attribute-sets. Например, в предыдущем преобразовании набор атрибутов elements мог быть определен как:
<xsl:attribute-set name="elements"
use-attribute-sets="attrs">
<xsl:attribute name="name">
<xsl:value-of select="name()"/>
</xsl:attribute>
<xsl:attribute name="node-count">
<xsl:value-of select="count(*)"/>
</xsl:attribute>
</xsl:attribute-set>
Тогда для достижения того же результата элемент с именем element мог быть создан с использованием только одного набора атрибутов:
<xsl:element name="element"
use-attribute-sets="elements">
<xsl:apply-templates select="*"/>
</xsl:element>
Именованный набор атрибутов не может прямо или косвенно (посредством других наборов атрибутов) использовать в значении use-attribute-sets себя самого. Такая ситуация породила бы бесконечный цикл. Вообще, не рекомендуется выстраивать сложную иерархию именованных наборов атрибутов, поскольку это может сильно усложнить обработку и снизить эффективность преобразования, хотя, естественно, все зависит от конкретного случая.