Вместо <xsl:variable name="elementposition" select="count(preceding-sibling::*)+1"/>
кажется, что вы можете просто использовать <xsl:variable name="pos" select="position()"/>
, а затем напрямую использовать, например, $personne2/personnes/personne[$pos]/id
, что, вероятно, повысит производительность, так как управляющее положение для функции position()
в любом случае выполняется эффективно при повторном подсчете братьев и сестери снова это дорого.
С процессором XSLT 2 вы также можете рассмотреть возможность использования ключа вместе с xsl:number
, например,
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:key name="pos" match="personne">
<xsl:variable name="pos" as="xs:integer">
<xsl:number/>
</xsl:variable>
<xsl:sequence select="$pos"/>
</xsl:key>
<xsl:output method="xml" indent="yes"/>
<!-- load the merge file
<xsl:variable name="personne2"
select="document('file2.xml')"/>-->
<!-- inlining here for the self-containedness of the example -->
<xsl:variable name="personne2">
<personnes>
<personne>
<id>1111</id>
<quantity>1100</quantity>
</personne>
<personne>
<id>2222</id>
<quantity>2200</quantity>
</personne>
<personne>
<id>3333</id>
<quantity>3300</quantity>
</personne>
<personne>
<id>4444</id>
<quantity>4400</quantity>
</personne>
<personne>
<id>5555</id>
<quantity>5500</quantity>
</personne>
</personnes>
</xsl:variable>
<xsl:template match="/">
<personnes>
<xsl:for-each select="personnes/personne">
<!-- copy the child nodes -->
<personne>
<xsl:copy-of select="key('pos', position(), $personne2)/id"/>
<xsl:copy-of select="child::name"/>
<xsl:copy-of select="key('pos', position(), $personne2)/quantity"/>
<xsl:copy-of select="child::age"/>
<xsl:copy-of select="child::address"/>
</personne>
</xsl:for-each>
</personnes>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty -development.net /bFN1y8Q
XSLT 3 имеет больше опций с аккумуляторами и xsl:merge
:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:accumulator name="pos" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="personnes" select="0"/>
<xsl:accumulator-rule match="personnes/personne" select="$value + 1"/>
</xsl:accumulator>
<xsl:mode use-accumulators="pos"/>
<xsl:output method="xml" indent="yes"/>
<!-- load the merge file
<xsl:variable name="personne2"
select="document('file2.xml')"/>-->
<!-- inlining here for the self-containedness of the example -->
<xsl:variable name="personne2">
<personnes>
<personne>
<id>1111</id>
<quantity>1100</quantity>
</personne>
<personne>
<id>2222</id>
<quantity>2200</quantity>
</personne>
<personne>
<id>3333</id>
<quantity>3300</quantity>
</personne>
<personne>
<id>4444</id>
<quantity>4400</quantity>
</personne>
<personne>
<id>5555</id>
<quantity>5500</quantity>
</personne>
</personnes>
</xsl:variable>
<xsl:template match="/*">
<xsl:copy>
<xsl:merge>
<xsl:merge-source select="personne">
<xsl:merge-key select="accumulator-before('pos')"/>
</xsl:merge-source>
<xsl:merge-source for-each-item="$personne2" select="personnes/personne">
<xsl:merge-key select="accumulator-before('pos')"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:copy>
<xsl:copy-of
select="current-merge-group()[2]/id, name, current-merge-group()[2]/quantity, age, adress"/>
</xsl:copy>
</xsl:merge-action>
</xsl:merge>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty -development.net / bFN1y8Q / 2