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

</xsclass="underline" element>

Здесь обязательный атрибут name указывает имя создаваемого элемента. Этот атрибут может содержать шаблон значения, а значит, имя элемента может быть вычислено во время выполнения.

Атрибут namespace указывает URI пространства имен создаваемого элемента. Точно так же, как и name, этот атрибут может содержать шаблон значения, что позволяет вычислять пространство имен создаваемого элемента при помощи выражений.

Атрибут use-attribute-sets перечисляет имена наборов атрибутов, которые должны быть включены в создаваемый элемент.

Содержимым xsclass="underline" element является шаблон, который выполняется процессором и затем включается в создаваемый элемент.

Пример

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

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

<fire on="babylon"/>

Листинг 7.2. Шаблон, заменяющий имя элемента значением атрибута

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

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

  <xsclass="underline" attribute name="{name(@*)}">

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

  </xsclass="underline" attribute>

 </xsclass="underline" element>

</xsclass="underline" template>

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

<babylon on="fire"/>

В этом примере код <xsclass="underline" element name="{@*}">...</xsclass="underline" element> создает элемент, именем которого становится значение выражения @*, указанного в виде шаблона значения атрибута name. Это выражение выбирает множество, состоящее из узлов атрибутов текущего элемента, а если привести его к строке, в результате получится текстовое значение первого атрибута элемента.

Подобным образом выбирается имя атрибута создаваемого элемента и его значение.

Вычисленное значение атрибута name может задавать и расширенное имя элемента, то есть иметь форму префикс:имя. В этом случае элемент будет создаваться в том пространстве имен, которое соответствует указанному префиксу, например

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

создаст элемент вида

<xsclass="underline" template xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>

Заметим, что элемент вида

<xsclass="underline" element name="{concat{'xsl',':','template')}"/>

даст тот же результат.

Другим способом указания пространства имен при использовании элемента xsclass="underline" element является использование атрибута namespace. Например, для предыдущего случая мы могли бы записать

<xsclass="underline" element

 name="template"

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

и получить в итоге

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

что эквивалентно результату предыдущего примера, хоть и различается внешне.

Атрибут namespace тоже может быть сконструирован на этапе выполнения, например:

<xsclass="underline" element

 name="template"

 namespace="{concat('http://www.w3.org/', 2001 - 2, '/XSL/Transform')}"/>

что также даст элемент template, принадлежащий пространству имен XSLT.

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

□ Если в элементе xsclass="underline" element определен атрибут namespace, то создаваемый элемент будет принадлежать пространству имен с URI, который будет значением этого атрибута. Если значением атрибута namespace будет пустая строка, создаваемый элемент будет принадлежать нулевому пространству имен. Как правило, процессоры используют префикс, указанный в имени атрибутом name, но, вместе с тем, они не обязаны так делать. Поэтому в общем случае следует ожидать, что префикс может быть любым.

□ Если в элементе xsclass="underline" element не определен атрибут namespace, но имя, заданное в атрибуте name имеет префикс, то создаваемый элемент будет принадлежать соответствующему этому префиксу пространству имен. Однако и в этом случае не гарантируется, что префикс создаваемого элемента будет таким, каким он был задан в атрибуте name.

□ В случае, если в элементе xsclass="underline" element не определен атрибут namespace и имя, заданное в атрибуте name не имеет префикса, создаваемый элемент будет принадлежать пространству имен, которое действует для создающего элемента xsclass="underline" element по умолчанию.

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

Приведем несколько примеров.

Для начала покажем, что, согласно первому правилу, атрибут namespace имеет наивысший приоритет при определении пространства имен выходящего элемента. Рассмотрим следующее преобразование.

Листинг 7.4.

<xsclass="underline" stylesheet

 version="1.0"

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

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

<xsclass="underline" element

 name="xsclass="underline" html"

 namespace="http://www.w3.org/1999/xhtml"/>

</xsclass="underline" template>

</xsclass="underline" stylesheet>

В выделенном элементе xsclass="underline" element пространство имен создаваемого элемента указано вроде бы два раза: в виде значения атрибута namespace и в виде префикса имени ("xsl"). Результат будет выглядеть следующим образом:

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

Процессор использовал пространство имен, указанное в атрибуте namespace, локальную часть имени, заданного атрибутом name ("html"), а также префикс (только префикс, но не связанное с ним пространство имен) этого имени ("xsl").

В свою очередь конструкция вида

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

создаст элемент

<xsclass="underline" html xmlns:xsl=""></xsclass="underline" html>

что на самом деле эквивалентно просто <html/>.

Таким образом, атрибут namespace наиболее приоритетен для определения пространства имен создаваемого элемента. Обратимся теперь к случаю, когда этот атрибут опущен в xsclass="underline" element. Объявление вида

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

создаст элемент

<xsclass="underline" html xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>

Как видим, отсутствие namespace и namespace="" — не одно и то же.

Рассмотрим теперь случай, когда нет ни атрибута namespace, ни префикса в name:

<xsclass="underline" stylesheet

 version="1.0"

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

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

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

</xsclass="underline" template>