Re: [xsl] Copying Node Multiple Time

Subject: Re: [xsl] Copying Node Multiple Time
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 5 Apr 2001 13:49:49 +0100
Hi Amarjit,

> I would like to use the quantity attribute to create multiple copies
> of the ItemIn node and set the quantity attribute to 1 and increment
> the line number. I have started with the following XSL code and
> would like to know how to create a loop to do multiple copies.

You need to use recursion to solve this problem.  Given an ItemIn
element with a quantity of 3, you want to copy that ItemIn element
(with appropriately changed attributes), and then apply templates to
it again, doing the same thing.  You can use parameters to keep track
of (a) how many more copies there are left to do and (b) which copy
this one will be.

<xsl:template match="ItemIn">
   <!-- $quantity gives the number left to copy - 'quantity' attribute
        by default -->
   <xsl:param name="quantity" select="@quantity" />
   <!-- $number keeps track of what number copy this one is -->
   <xsl:param name="number" select="1" />
   
   <!-- copy the element with the lineNumber attribute equal to the
        number of this copy -->
   <ItemIn quantity="1" lineNumber="{$number}">
      <!-- copy all its child nodes -->
      <xsl:copy-of select="node()" />
   </ItemIn>

   <!-- if the quantity is more than 1... -->
   <xsl:if test="$quantity > 1">
      <!-- apply templates to the same ItemIn element again, this time
           with the $quantity parameter equal to one less than it was,
           and the $number parameter equal to one more than it was -->
      <xsl:apply-templates select=".">
         <xsl:with-param name="quantity" select="$quantity - 1" />
         <xsl:with-param name="number" select="$number + 1" />
      </xsl:apply-templates>
   </xsl:if>
</xsl:template>

With this template in place, you just need to apply templates to the
ItemIn elements in the old Cart to get the new one.  The default
values for the parameters make sure that the correct values for
$quantity and $number are used, so you don't have to pass in anything:

<xsl:template match="/">
   <NewCart>
      <xsl:apply-templates select="ItemIn" />
   </NewCart>
</xsl:template>

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread