Вот альтернативный способ, хотя я понятия не имею, улучшает ли он производительность или нет.
Сначала создайте переменную, которую можно эффективно использовать для сопоставления элементов value
с их положением
<xsl:variable name="attributes">
<xsl:for-each select="//n:attribute[n:name = 'order']/n:value">
<n:value key="{generate-id()}" pos="{position()}" />
</xsl:for-each>
</xsl:variable>
Затем создайте ключ для поиска этих значений
<xsl:key name="attributes" match="n:value" use="@key" />
Затем, вместо использования xsl:number
, получите позицию следующим образом:
<xsl:value-of select="key('attributes', generate-id(), $attributes)/@pos" />
Например, с учетом этого XML
<root xmlns="n">
<attribute>
<name>order</name>
<value></value>
</attribute>
<attribute>
<name>order</name>
<value></value>
</attribute>
<children>
<attribute>
<name>order</name>
<value></value>
</attribute>
</children>
</root>
А это XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:n="n" exclude-result-prefixes="n">
<xsl:key name="attributes" match="n:value" use="@key" />
<xsl:variable name="attributes">
<xsl:for-each select="//n:attribute[n:name = 'order']/n:value">
<n:value key="{generate-id()}" pos="{position()}" />
</xsl:for-each>
</xsl:variable>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="n:attribute[n:name = 'order']/n:value">
<value xmlns="n">
<xsl:value-of select="key('attributes', generate-id(), $attributes)/@pos" />
</value>
</xsl:template>
</xsl:stylesheet>
Результат таков:
<attribute>
<name>order</name>
<value>1</value>
</attribute>
<attribute>
<name>order</name>
<value>2</value>
</attribute>
<children>
<attribute>
<name>order</name>
<value>3</value>
</attribute>
</children>
</root>