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

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

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

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

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

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

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

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

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

<xsclass="underline" attribute-set

 name="имя"

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

 <!-- Содержимое: несколько элементов xsclass="underline" attribute -->

</xsclass="underline" attribute-set>

Для того чтобы упростить создание в элементах целых наборов атрибутов, можно заранее определить их в элементе xsclass="underline" attribute-set. Обязательный атрибут name задает имя набора атрибутов. Элемент xsclass="underline" attribute-set содержит последовательность, состоящую из нуля или более элементов xsclass="underline" attribute.

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

Включение набора атрибутов в элемент равносильно простому копированию элементов xsclass="underline" attribute, определенных в соответствующих элементах xsclass="underline" 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. Преобразование

<xsclass="underline" stylesheet

 version="1.0"

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

 <xsclass="underline" output indent="yes"/>

 <xsclass="underline" attribute-set name="attrs">

  <xsclass="underline" attribute name="attr-count">

   <xsclass="underline" value-of select="count(@*)"/>

  </xsclass="underline" attribute>

 </xsclass="underline" attribute-set>

 <xsclass="underline" attribute-set name="elements">

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

   <xsclass="underline" value-of select="name()"/>

  </xsclass="underline" attribute>

  <xsclass="underline" attribute name="node-count">

   <xsclass="underline" value-of select="count(*)"/>

  </xsclass="underline" attribute>

 </xsclass="underline" attribute-set>

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

  <xsclass="underline" element name="element"

   use-attribute-sets="elements attrs">

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

  </xsclass="underline" element>

 </xsclass="underline" template>

</xsclass="underline" 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>

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

<xsclass="underline" element name="element"

 use-attribute-sets="elements attrs">

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

</xsclass="underline" element>

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

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

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

  <xsclass="underline" value-of select="name()"/>

 </xsclass="underline" attribute>

 <xsclass="underline" attribute name="node-count">

  <xsclass="underline" value-of select="count(*)"/>

 </xsclass="underline" attribute>

 <xsclass="underline" attribute name="attr-count">

  <xsclass="underline" value-of select="count(@*)"/>

 </xsclass="underline" attribute>

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

</xsclass="underline" element>

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

<xsclass="underline" attribute-set name="elements"

 use-attribute-sets="attrs">

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

  <xsclass="underline" value-of select="name()"/>

 </xsclass="underline" attribute>

 <xsclass="underline" attribute name="node-count">

  <xsclass="underline" value-of select="count(*)"/>

 </xsclass="underline" attribute>

</xsclass="underline" attribute-set>

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

<xsclass="underline" element name="element"

 use-attribute-sets="elements">

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

</xsclass="underline" element>

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

Атрибут xsclass="underline" use-attribute-sets

Мы упомянули о том, что именованные наборы атрибутов используются в элементах посредством атрибута xsclass="underline" use-attribute-sets. Разберем более детально, где этот атрибут может применяться, и какие функции он при этом выполняет. Для удобства эти данные сведены в табл. 7.1.

Таблица 7.1. Использование атрибута xsclass="underline" use-attribute-sets

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