Re: [xsl] Counting and Rearranging Nodes

Subject: Re: [xsl] Counting and Rearranging Nodes
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Thu, 22 Jun 2006 10:52:59 +0530
Hi Rostom,
 Please try this stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:output method="xml" indent="yes" />

   <xsl:template match="/Root">
       <Root>
           <xsl:for-each select="Item">
             <xsl:sort select="Line_No" data-type="number" />
                <New_Item>
                  <xsl:variable name="x" select="Line_No -
substring(Line_No, string-length(Line_No), 1) + 1" />
                  <Line_No><xsl:value-of select=" $x +
count(preceding::Line_No[(. - substring(., string-length(.), 1) + 1) =
$x])" /></Line_No>
	   <Line_No_Og><xsl:value-of select=" Line_No" /></Line_No_Og>	
<Amount><xsl:value-of select="Amount" /></Amount>
               </New_Item>
           </xsl:for-each>
       </Root>
   </xsl:template>

</xsl:stylesheet>

Regards,
Mukul

On 6/22/06, rostom aghanian <rostom@xxxxxxxx> wrote:
Hello,
I need some help on traversing an XML structure and outputting the entries in a specific format. Here it goes....

My input structure looks something like this:

<Root>
 <Item>
     <Line_No>901</Line_No>
     <Amount>50.00</Amount>
 </Item>
 <Item>
   <Line_No>801</Line_No>
   <Amount>60.00</Amount>
 </Item>
 <Item>
   <Line_No>802</Line_No>
   <Amount>77.00</Amount>
 </Item>
 <Item>
   <Line_No>806</Line_No>
   <Amount>99.00</Amount>
 </Item>
 <Item>
   <Line_No>1002</Line_No>
   <Amount>3.00</Amount>
 </Item>
 <Item>
   <Line_No>1003</Line_No>
   <Amount>5.00</Amount>
 </Item>
</Root>

For my output I want something like the following:

<Root>
 <New_Item>
   <Line_No>801</Line_No>
   <Line_No_Og>801</Line_No_Og>
   <Amount>60.00</Amount>
 </New_Item>
 <New_Item>
   <Line_No>802</Line_No>
   <Line_No_Og>802</Line_No_Og>
   <Amount>77.00</Amount>
 </New_Item>
 <New_Item>
   <Line_No>803</Line_No>
   <Line_No_Og>806</Line_No_Og>
   <Amount>99.00</Amount>
 </New_Item>
 <New_Item>
   <Line_No>901</Line_No>
   <Line_No_Og>901</Line_No_Og>
   <Amount>60.00</Amount>
 </New_Item>
 <New_Item>
   <Line_No>1001</Line_No>
   <Line_No_Og>1002</Line_No_Og>
   <Amount>3.00</Amount>
 </New_Item>
 <New_Item>
   <Line_No>1002</Line_No>
   <Line_No_Og>1003</Line_No_Og>
   <Amount>5.00</Amount>
 </New_Item>
</Root>

Explanation and a few important points:
- Basically, I am trying to get the items renumbered based on their Line_No element.

- The Line_No element will never end with a 00 (i.e. 800, 900, 1000).

- The Line_No element may skip (i.e. 801, 802, 806), but in my output I want to keep them ordered (i.e. 801, 802, 803), as demostrated in the above XML snippets.

- The result does not need to have the Line_No or Line_No_Og elements in order, but it does need to restart the Line_No_Og numbering based on the hundreth group the Line_No element is in. For example:
 801  --> 801  (begin 800 group)
 802  --> 802
 806  --> 803  (notice new Line_No is continuous, wheras original skipped)
 901  --> 901  (notice numbering re-starts at the 1s for a new group (900s))
 1002 --> 1001 (notice numbering re-starts at the 1s for a new group (1000s))
 1003 --> 1002 (numbering continues consecutively in the 1000's group)

- And lastly, keep in mind that the Line_No elements can go up to the max (i.e. 899, 999, and 1099).

Any help would be greatly appreciated. Thanks in advance.

rostom

Current Thread