Теперь для проверки в цикле <xsl:for-each>
того, что текущий элемент не является контекстным узлом, я могу обратиться к контекстному узлу шаблона как $contextnode
(листинг 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, этот пример работать не будет. Как же тогда сохранить весь элемент буквального результата одновременно с возможностью простого вызова? Вы можете создать именованный шаблон.