I have some source XML containing different elements that get transformed by a stylesheet into output elements with the same name. The output elements then require an ‘index’ element on each one.
My first choice was using position(), but of course that only works for the context of the xsl:for-each in which they’re positioned.
Here is a sample XML:
<Root>
<TypeA Val="First Value"/>
<TypeA Val="Second Value"/>
<NotToBeTransformed Val="ignoreme"/>
<TypeB Val="Third Value"/>
<TypeB Val="Fourth Value"/>
</Root>
And here is how I would like it to be rendered as output:
<Output>
<Destination>
<Index>1</Index>
<Content>First Value</Content>
</Destination>
<Destination>
<Index>2</Index>
<Content>Second Value</Content>
</Destination>
<Destination>
<Index>3</Index>
<Content>Third Value</Content>
</Destination>
<Destination>
<Index>4</Index>
<Content>Fourth Value</Content>
</Destination>
</Output>
My simple XSLT is as follows:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<Output>
<xsl:for-each select="//TypeA">
<Destination>
<Index><xsl:value-of select="position()"/></Index>
<Content><xsl:value-of select="@Val"/></Content>
</Destination>
</xsl:for-each>
<xsl:for-each select="//TypeB">
<Destination>
<Index><xsl:value-of select="position()"/></Index>
<Content><xsl:value-of select="@Val"/></Content>
</Destination>
</xsl:for-each>
</Output>
</xsl:template>
But that outputs the Index with values of 1 and 2 for each of the collections of source elements.
Can this be done in XSLT or would this need to be processed again? I’m doing the transform with C# code, so I could run an initial transform and then set the Index values in code afterwards.
Any help would be most gratefully accepted!
You don’t need to use
xsl:for-eachat all (try always to avoid it), neither it is necessary to processTypeAandTypeBelements separately.This transformation:
when applied on the provided XML document:
produces the wanted, correct result: