<xsl:variable name='movie' select=''Goldfinger''/><!-- Запрещено -- >
Несмотря на все эти ограничения, вы<xsl:for-each>
, как мы увидим в следующем разделе.
Работа с переменными
Давайте рассмотрим примеры применения переменных. В следующем примере (листинг 9.1) я присваиваю переменной copyright
сообщение об авторских правах и затем с ее помощью добавляю атрибут copyright
во все элементы planets.xml
.
<?xml version='1.0'?>
<xsl:stylesheet version='1.1'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml'/>
<xsl:variable name='copyright' select=''(c)2002 Starpowder Inc.''/>
<xsl:template match='*'>
<xsl:copy>
<xsl:attribute name='copyright'>
<xsl:value-of select='$copyright'/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Вот результирующий документ, дополненный атрибутами copyright
<?xml version='1.0' encoding='utf-8'?>
<PLANETS copyright='(c)2002 Starpowder Inc.'>
<PLANET copyright='(c)2002 Starpowder Inc.'>
<NAME copyright='(c)2002 Starpowder Inc.'>Mercury</NAME>
<MASS copyright='(c)2002 Starpowder Inc.'>.0553</MASS>
<DAY copyright='(с)2002 Starpowder Inc.'>58.65</DAY>
<RADIUS copyright='(c)2002 Starpowder Inc.'>1516</RADIUS>
<DENSITY copyright='(c)2002 Starpowder Inc.'>.983</DENSITY>
<DISTANCE copyright='(с)2002 Starpowder Inc.'>43.4</DISTANCE>
</PLANET>
<PLANET copyright='(c)2002 Starpowder Inc.'>
<NAME copyright='(c)2002 Starpowder Inc.'>Venus</NAME>
<MASS copyright='(c)2002 Starpowder Inc.'>.815</MASS>
<DAY copyright='(с)2002 Starpowder Inc.'>116.75</DAY>
<RADIUS copyright='(c)2002 Starpowder Inc.'>3716</RADIUS>
<DENSITY copyright='(c)2002 Starpowder Inc.'>.943</DENSITY>
<DISTANCE copyright='(c)2002 Starpowder Inc.'>66.8</DISTANCE>
</PLANET>
.
.
.
Переменные зачастую удобны для хранения значении, зависимых от контекста, и мы сейчас рассмотрим еще один пример, о котором я упоминал в начале главы. В этом случае я преобразую planets.xml
в новый документ, в котором для каждой планеты будет один элемент. Каждый из этих новых элементов будет содержать два элемента <SIBLINGPLANET>
, содержащих планеты-братья текущей планеты — например, братьями Земли будут Венера и Меркурий:
<?xml version='1.0' encoding='utf-8'?>
<Mercury>
<SIBLINGPLANET>
Venus
</SIBLINGPLANET>
<SIBLINGPLANET>
Earth
</SIBLINGPLANET>
</Mercury>
<Venus>
<SIBLINGPLANET>
Mercury
</SIBLINGPLANET>
<SIBLINGPLANET>
Earth
</SIBLINGPLANET>
</Venus>
<Earth>
<SIBLINGPLANET>
Mercury
</SIBLINGPLANET>
<SIBLINGPLANET>
Venus
</SIBLINGPLANET>
</Earth>
Для примера я поочередно выбираю каждый элемент <PLANET>
и прохожу в цикле <xsl:for-each>
по всем планетам, создавая элементы <SIBLINGPLANET>
для всех планет, не являющихся контекстным узлом. Однако откуда мне известно внутри элемента <xsl:for-each>
, какая из планет является контекстным узлом, выбранным шаблоном? Внутри элемента <xsl:for-each>
«.» ссылается на текущий узел, с которым работает <xsl:for-each>
, но не на контекстный узел шаблона. Проблему можно решить, если сохранить контекстный узел в переменной, которую я назвал contextnode
:
<?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='.'/>
.
.
.