I am trying to generate a three digit counter like 001, 002 .... i have declared two counter variables with same name will it work? i have defined one global variable and one within loop for incrementing counter will it generate correct values? here is my code
<xsl:template match="/">
<xsl:variable name="counter" select="001"/>
<xsl:for-each select="ns0:Notes/ns0:Note">
<ORDER_LINE_NOTE_SEG>
<NOTLIN>
<xsl:value-of select="$counter"/>
</NOTLIN>
</ORDER_LINE_NOTE_SEG>
<xsl:variable name="counter" select="number(counter) 1"/>
</xsl:for-each>
</xsl:template>
Required output
<ORDER_LINE_NOTE_SEG>
<NOTLIN>001</NOTLIN>
</ORDER_LINE_NOTE_SEG>
<ORDER_LINE_NOTE_SEG>
<NOTLIN>002</NOTLIN>
</ORDER_LINE_NOTE_SEG>
<ORDER_LINE_NOTE_SEG>
<NOTLIN>003</NOTLIN>
</ORDER_LINE_NOTE_SEG>
CodePudding user response:
When referring to a variable in XSLT, you have to prefix it with $
, but that's not the main issue, which is that you cannot do this in XSLT:
<xsl:variable name="counter" select="number($counter) 1"/>
Variables in XSLT are immutable. You cannot re-assign a new value to a variable.
But inside your xsl:for-each
statement, you can refer to the position of the current ns0:Note
element in the sequence using the position()
function, which will return 1
for the first ns0:Note
, 2
for the second, etc.
CodePudding user response:
You did not post an example input, which makes answering more difficult and time-consuming. Consider an input like:
XML
<Notes>
<Note/>
<Note/>
<Note/>
</Notes>
Here you have 2 options to get the output you show:
XSLT 1.0 [#1]
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Notes">
<xsl:for-each select="Note">
<ORDER_LINE_NOTE_SEG>
<NOTLIN>
<xsl:value-of select="format-number(position(), '000')"/>
</NOTLIN>
</ORDER_LINE_NOTE_SEG>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0 [#2]
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Notes">
<xsl:for-each select="Note">
<ORDER_LINE_NOTE_SEG>
<NOTLIN>
<xsl:number format="001"/>
</NOTLIN>
</ORDER_LINE_NOTE_SEG>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Note that the result in both cases is an XML fragment, not a well-formed XML document because it has no single root element.
As already mentioned in the other answer, your attempt using a variable cannot work. Not only because a variable is immutable, but mainly because xsl:for-each
is not a "loop": results of one iteration cannot be passed to another.
If you wanted, you could use a named recursive template to increment a counter on each successive call. But it would really be an overcomplication in this case.