Friday, 31 October 2014

Incremenent counter in nested for loop and maintain parent-child relationship(XSLT)


My requirement was to increment counter for each order and orderitems table. It is very simple in C# because
you can set the value of variable in each loop but in XSLT once you declare the variable you can not
change it. I have tried with couple of hours and at last found solution with scripting function in XSLT.

Below is my input XML

<orders>
<orderItems>
<Name>Test1</Name>
</orderitems>
<orderItems>
<Name>Test2</Name>
</orderitems>
<orderItems>
<Name>Test3</Name>
</orderitems>
</Orders>
<orders>
<orderItems>
<Name>Test4</Name>
</orderitems>
<orderItems>
<Name>Test5</Name></orderitems>
</Orders>

And here is my output XML.

I want to loop through all orders and orderitems and create seperate node and maintain parent- child
relationship.


<orderItems>
<Id>1 </Id>
<Name></Name>
<ParentID>0</ParentID>
</orderitems>
<orderItems>
<Id>2</Id>
<Name>Test1</Name>
<ParentID>1</ParentID>
</orderitems>
<orderItems>
<Id>3</Id>
<Name>Test2</Name>
<ParentID>1</ParentID>
</orderitems>
<orderItems>
<Id>4</Id>
<Name>Test3</Name>
<ParentID>1</ParentID>
</orderitems>

<orderItems>
<Id>5</Id>
<Name></Name>
<ParentID>0</ParentID>
</orderitems>
<orderItems>
<Id>6</Id>
<Name>Test4</Name>
<ParentID>5</ParentID>
</orderitems>
<orderItems>
<Id>7</Id>
<Name>Test5</Name>
<ParentID>5</ParentID>
</orderitems>

Here is my XSLT file

<xsl:for-each select="Orders">
     <xsl:variable name="var:v3" select="userCSharp:AddToCounter()" />
        <xsl:variable name="var:v5" select="userCSharp:GetCounter()" />


          <OrderItems>
      <Id><xsl:value-of select="userCSharp:GetCounter()"/></Id>
<Name>Test5</Name>
<ParentID>0</ParentID>
</orderitems>

    <xsl:for-each select="OrderItems">
            <xsl:variable name="var:v4" select="userCSharp:AddToCounter()" />
     <OrderItems>
      <Id><xsl:value-of select="userCSharp:GetCounter()"/></Id>
<Name>   <xsl:value-of select="$var:v5"/> </Name>
<ParentID>0</ParentID>
</orderitems>


    </xsl:for-each>
</xsl:for-each>

   
Add below script

 <msxsl:script language="C#" implements-prefix="userCSharp">
    <![CDATA[
    int mCounter= 1;
    public bool  AddToCounter()
    {
      mCounter = mCounter + 1;
      return true;
    }
 
    public int GetCounter()
    {
      return mCounter;
    }
   ]]>
  </msxsl:script>

No comments:

Post a Comment