The key is a function position(). It works as with <xsl:for-each>:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/reference">
<services>
<xsl:for-each select="*[starts-with(local-name(), 'ref_name_')][. != '']">
<xsl:variable name="originalNumber" select="substring-after(local-name(), 'ref_name_')"/>
<service name="reference" id="{position()}">
<name>
<xsl:value-of select="."/>
</name>
<company>
<xsl:value-of select="following-sibling::*[local-name()=concat('ref_company_', $originalNumber)][1]"/>
</company>
<position>
<xsl:value-of select="following-sibling::*[local-name()=concat('ref_position_', $originalNumber)][1]"/>
</position>
</service>
</xsl:for-each>
</services>
</xsl:template>
</xsl:stylesheet>
As with <xsl:apply-tempaltes>:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/reference">
<services>
<xsl:apply-templates select="*[starts-with(local-name(), 'ref_name_')][. != '']"/>
</services>
</xsl:template>
<xsl:template match="*[starts-with(local-name(), 'ref_name_')][. != '']">
<xsl:variable name="originalNumber" select="substring-after(local-name(), 'ref_name_')"/>
<service name="reference" id="{position()}">
<name>
<xsl:value-of select="."/>
</name>
<company>
<xsl:value-of select="following-sibling::*[local-name()=concat('ref_company_', $originalNumber)][1]"/>
</company>
<position>
<xsl:value-of select="following-sibling::*[local-name()=concat('ref_position_', $originalNumber)][1]"/>
</position>
</service> </xsl:template>
</xsl:stylesheet>
source
share