xsl-list
[Top] [All Lists]

Re: Traversing the tree

2005-09-12 03:53:59
On 9/11/05, Michael Kay <mike(_at_)saxonica(_dot_)com> wrote:
This kind of problem is best tackled using recursion. It's difficult to
write your first recursive stylesheet, but it's a very powerful technique to
have under your belt.

Basically you need to write a template that processes one of the siblings,
passing it the value of your "counter" or "running-total" as a parameter.
The template needs to make whatever changes are necessary to the counter or
running total, then make a recursive call to process the next element if
there is one, passing the new value of the counter or running total as a
parameter. When the final sibling is reached, you return (or write to the
output) the final value of the counter.

You can do this either with call-template or apply-templates (perhaps using
a special mode). I find it easier to use apply-templates, for two reasons:
(a) the current node is passed as an implicit parameter, and (b) the
recursion often terminates naturally when there are no more siblings.

Here's an example that totals @price*(_at_)qty over a set of sibling elements:

<xsl:template match="order">
 <total-value>
   <xsl:apply-template select="order-item[1]">
     <xsl:with-param name="running-total" select="0"/>
   </xsl:apply-templates>
 </total-value>
</xsl:template>

<xsl:template match="order-item">
 <xsl:param name="running-total"/>
 <xsl:choose>
   <xsl:when test="following-sibling::order-item">
   <xsl:apply-template select="following-sibling::order-item[1]">
     <xsl:with-param name="running-total" select="$running-total +
(@price*(_at_)qty)"/>
   </xsl:apply-templates>
   </xsl:when>
   <xsl:otherwise>
     <xsl:value-of select="$running-total + (@price*(_at_)qty)"/>
   </xsl:otherwise>
 </xsl:choose>
</xsl:template>


Or using FXSL:

      <xsl:value-of select=
      "f:foldl(f:add(), 
               0, 
               f:zipWith(f:mult(),/*/*/@price, /*/*/@qty)
               )"/>


Cheers,
Dimitre Novatchev

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>