того, что текущий элемент не является контекстным узлом, я могу обратиться к контекстному узлу шаблона как
$contextnode
(листинг 9.2).
Листинг 9.2. Хранение в переменной информации, зависимой от контекста
<?xml version="1.0"?>
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="PLANETS">
<xsl:for-each select="PLANET">
<xsl:element name="{NAME}">
<xsl:variable name="contextnode" select="."/>
<xsl:for-each select="//PLANET">
<xsl:if test=". != $contextnode">
<xsl:element name="SIBLINGPLANET">
<xsl:value-of select="NAME"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Теперь
наша проблема решена.
Если у элемента
<xsl:variable>
есть тело, он создает переменную, чье значение является фрагментом результирующего дерева. В следующем примере при помощи фрагмента результирующего дерева я задаю значение по умолчанию для атрибута
COLOR
(цвет), если значение для него уже не задано. Значение по умолчанию я устанавливаю в «
blue
» (голубой):
<xsl:variable name="COLOR">
<xsl:choose>
<xsl:when test="@COLOR">
<xsl:value-of select="@COLOR"/>
</xsl:when>
<xsl:otherwise>blue</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Строковое значение фрагмента результирующего дерева (то есть либо значение атрибута
COLOR
, либо значение по умолчанию, «
blue
») присваивается переменной
COLOR
. Теперь в выражениях XPath можно обращаться к значению этой переменной,
$COLOR
, а не к значению атрибута (
@COLOR
, гарантированно получая при этом значение цвета, даже если у соответствующего элемента отсутствует атрибут
COLOR
.
Вот еще один пример фрагмента результирующего дерева. В этом случае я сохраняю элемент буквального результата в переменной
START_HTML
:
<?xml version="1.0"?>
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="START_HTML">
<HEAD>
<TITLE>
My page
</TITLE>
</HEAD>
</xsl:variable>
.
.
.
Теперь
я могу использовать этот элемент буквального результата где угодно:
<?xml version="1.0"?>
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:variable name="START_HTML">
<HEAD>
<TITLE>
My page
</TITLE>
</HEAD>
</xsl:variable>
<xsl:template match="PLANETS">
<HTML>
<xsl:copy-of select="$START HTML"/>
<BODY>
<H1>Welcome to my page</H1>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
И вот результат:
<HTML>
<HEAD>
<TITLE>
My page
</TITLE>
</HEAD>
<BODY>
<H1>Welcome to my page</H1>
</BODY>
</HTML>
Однако поскольку теперь фрагменты результирующего дерева не допускаются в XSLT 1.1, этот пример работать не будет. Как же тогда сохранить весь элемент буквального результата одновременно с возможностью простого вызова? Вы можете создать именованный шаблон.
Элемент <xsl:call-template>: применение именованных шаблонов
У элемента
<xsl:template>
есть атрибут
name
, задающий имя шаблона. Предположим, у меня есть элемент буквального результата, состоящий из двух элементов
<BR>
и двух элементов
<HR>
HTML, при помощи которого я создаю в документах HTML вертикальный разделитель:
<BR/>
<HR/>
<BR/>
<HR/>
Тогда я могу создать шаблон с именем «separator» (разделитель), использующий этот элемент буквального результата:
<xsl:template name="separator">
<BR/>
<HR/>
<BR/>
<HR/>
</xsl:template>
Это именованный шаблон — для его создания нужно только присвоить имя атрибуту name элемента