<xsl:template match='*'>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match='PLANET'>
<xsl:copy use-attribute-sets='numbering'>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:attribute-set name='numbering'>
<xsl:attribute name='number'><xsl:number/></xsl:attribute>
<xsl:attribute name='total'>
<xsl:value-of select='count(//PLANET)'/>
</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>
Ниже показан результат; заметьте, что у каждого элемента <PLANET>
есть оба атрибута, number
и total
, и атрибут total
содержит общее число элементов <PLANET>
в документе:
<?xml version='1.0' encoding='UTF-8'?>
<PLANETS>
<PLANET number='1' total='3'>
<NAME>Mercury</NAME>
<MASS>.0553</MASS>
<DAY>58.65</DAY>
<RADIUS>1516</RADIUS>
<DENSITY>.983</DENSITY>
<DISTANCE>43.4</DISTANCE>
</PLANET>
<PLANET number='2' total='3'>
<NAME>Venus</NAME>
<MASS>.815</MASS>
<DAY>116.75</DAY>
<RADIUS>3716</RADIUS>
<DENSITY>.943</DENSITY>
<DISTANCE>66.8</DISTANCE>
</PLANET>
<PLANET number='3' total='3'>
<NAME>Earth</NAME>
<MASS>1</MASS>
<DAY>1</DAY>
<RADIUS>2107</RADIUS>
<DENSITY>1</DENSITY>
<DISTANCE>128.4</DISTANCE>
</PLANET>
</PLANETS>
Среди функций для работы с наборами узлов в особенности обратите внимание на функции name
и local-name
. С их помощью можно определить имя текущего элемента: например, если текущим элементом является <DAY>
, local- name
вернет DAY
. Следующая таблица стилей демонстрирует, для чего это может понадобиться; в ней я использую такие теги, как <PLANETS>
, <PLANET>
и <DATA>
, в качестве элементов буквального результата:
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml'/>
<xsl:template match='PLANETS'>
<PLANETS>
<xsl:for-each select='PLANET'>
<PLANET>
<xsl:for-each select='*'>
<DATA>
<xsl:value-of select='.'/>
</DATA>
</xsl:for-each>
</PLANET>
</xsl:for-each>
</PLANETS>
</xsl:template>
</xsl:stylesheet>
Однако в таком случае разметка трактуется как простой текст. Вместо этого можно создать новые элементы при помощи <xsl:element>
, определяя имена контекстных узлов через local-name
:
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml'/>
<xsl:template match='PLANETS'>
<xsl:element name='{local-name(.)}'>
<xsl:for-each select='PLANET'>
<xsl:element name='{local-name(.)}'>
<xsl:for-each select='*'>
<xsl:element name='DATA'>
<xsl:value-of select='.'/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Ряд пишущих об XSLT авторов рассматривает выражения XSLT только как выражения, возвращающие наборы узлов. Но выражения XPath возвращают также логические значения, числа и строки, которые используются в элементах <xsl:param>
, <xsl:with-param>, <xsl:number>
, <xsl:value-of>
, <xsl:sort>
,