[xsl] Re: accumulate a variable...is it possible?

Subject: [xsl] Re: accumulate a variable...is it possible?
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Wed, 9 Oct 2002 12:34:13 -0700 (PDT)
--- Carter, Will  wrote:

> Hi,
> 
> I am trying to accumulate a variable but not succesful... here is my
> xml:
> --------------------------------
> <numbers>
>   <num>3</num>
>   <num>7</num>
>   <num>11</num>
>   <num>6</num>
>   <num>3</num>
> </numbers>
> --------------------------------
> 
> here is the output I want:
> --------------------------------
> num=3 accumulated=3 
> num=7 accumulated=10 
> num=11 accumulated=21 
> num=6 accumulated=27 
> num=3 accumulated=30
> --------------------------------
> 
> here is my stylesheet:
> --------------------------------
> <?xml version="1.0" encoding="ISO-8859-1"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> version="1.0">
> <xsl:template match="/">
> <xsl:variable name="acc" select="0"/>
> <table border="1">
>   <xsl:for-each select="numbers/num">
>   <xsl:variable name="acc" select="$acc + ."/>
>     <tr>
>       <td>num=<xsl:value-of select="."/></td>
>       <td>accumulated=<xsl:value-of select="$acc"/></td>
>     </tr>
>    </xsl:for-each>
> </table>
> </xsl:template>
> </xsl:stylesheet>
> --------------------------------
> 
> here is what I get:
> --------------------------------
> num=3 accumulated=3 
> num=7 accumulated=7 
> num=11 accumulated=11 
> num=6 accumulated=6 
> num=3 accumulated=3
> --------------------------------
> 
> this post is speaking the same problem, but I want to see the 3, 10,
> 21, 27, 30 along the way...
> http://p2p.wrox.com/archive/xslt/2002-04/57.asp
> 
> thanks,
> will

Hi Will,

Use the "scanl" or "scanl1" template from FXSL. They do exactly what
you want, are general enough to be used on any computation that is
gradually calculated by traversing a list.

With your source xml:
--------------------
<numbers>
  <num>3</num>
  <num>7</num>
  <num>11</num>
  <num>6</num>
  <num>3</num>
</numbers>


and this transformation:
-----------------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:myAdd="f:myAdd"
xmlns:myParam="f:myParam"
>
  <xsl:import href="scanlDVC.xsl"/>
  <!-- to be applied on numList.xml -->
  
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <myAdd:myAdd/>
  
  <myParam:myParam>0</myParam:myParam>
  
  <xsl:template match="/">
   
    <xsl:variable name="vFun" select="document('')/*/myAdd:*[1]"/>
    <xsl:variable name="vZero" select="document('')/*/myParam:*[1]"/>

    
    <xsl:call-template name="scanl">
      <xsl:with-param name="pFun" select="$vFun"/>
      <xsl:with-param name="pQ0" select="$vZero" />
      <xsl:with-param name="pList" select="/*/num"/>
    </xsl:call-template>
    
    - - - - - - - - - - -
    
     <xsl:call-template name="scanl1">
      <xsl:with-param name="pFun" select="$vFun"/>
      <xsl:with-param name="pList" select="/*/num"/>
    </xsl:call-template>
    
  </xsl:template>
  
  <xsl:template match="myAdd:*">
    <xsl:param name="pArg1" select="0"/>
    <xsl:param name="pArg2" select="0"/>
  
    <xsl:value-of select="$pArg1 + $pArg2"/>
  </xsl:template>
  
</xsl:stylesheet>


The result is:
-------------
<el>0</el>
<el>3</el>
<el>10</el>
<el>21</el>
<el>27</el>
<el>30</el>
    
    - - - - - - - - - - -
    
<el>3</el>
<el>10</el>
<el>21</el>
<el>27</el>
<el>30</el>


Please, also note that this transformation is quite efficient, having a
linear time and space complexity only.

Hope this helped.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com

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


Current Thread