Search code examples
xmlxsltpositionxslt-2.0xpath-2.0

Increment the element value in output based on the occurrence of an element in input


Hello I am trying to write xslt where when similar input below is given I would need to get a desired output. if you observe the output has an id based on the occurrence of an element in that xml. So far in my xslt i am doing it based on the position. but it breaks and restarts the count for every from Input XML. Can this be achieved.

update:

Adding some more details to the input. As you see I added under level and that should be populated on all of its respective data

Input XML

<lines>
    <line>
      <po-num>text1</ponum>
        <accountings>
            <accounting>
                <account>
                    <seg1>value1</seg1>
                </account>
            </accounting>
            <accounting>
                <account>
                    <seg1>value2</seg1>
                </account>
            </accounting>
        </accountings>
    </line>
    <line>
       <po-num>text2</ponum>
        <accountings>
            <accounting>
                <account>
                    <seg1>value3</seg1>
                </account>
            </accounting>
        </accountings>
    </line>
    <line>
       <po-num>text3</ponum>
        <account>
            <seg1>value4</seg1>
        </account>
    </line>
</lines>

Desired Output XML

<Item>
    <id>1</id>
    <po-num>text1</ponum>
    <seg>value1</seg>
</Item>
<Item>
    <id>2</id>
    <po-num>text1</ponum>
    <seg>value2</seg>
</Item>
<Item>
    <id>3</id>
    <po-num>text2</ponum>
    <seg>value3</seg>
</Item>
<Item>
    <id>4</id>
     <po-num>text3</ponum>
    <seg>value4</seg>
</Item>

XSLT I am using the xslt provided by Rupesh.

<?xml version="2.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"></xsl:output>
<xsl:template match = "/">

    <xsl:for-each select="//account">
        <item>
            <id><xsl:value-of select="position()"/></id>
             <po-num><xsl:value-of select="../../../*:po-num"/></po-num>
            <seg><xsl:value-of select="./*:seg1"></xsl:value-of></seg>
        </item>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Solution

  • Try this:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output indent="yes"></xsl:output>
        <xsl:template match = "/">
    
            <xsl:for-each select="//seg1">
                <item>
                    <id><xsl:value-of select="position()"/></id>
                    <seg><xsl:value-of select="."></xsl:value-of></seg>
                </item>
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>
    

    you can see transformation at http://xsltransform.hikmatu.com/jyyiVhm