Home > Blockchain >  xsl variable defined twice with same
xsl variable defined twice with same

Time:07-06

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.

  • Related