[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Re: Re: How to Calculate Running Total using Varia

Subject: Re: Re: Re: How to Calculate Running Total using Variable within FOR-LOOP?
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Mon, 8 Dec 2003 06:42:25 +0100
scanl
Hi Bill,

You need just scanl (scanl1 is a variation of scanl which supposes that the
provided list is non-empty (there is at least one element in the list)).

If you're interested in this topic downloading FXSL will be the right thing
to do.

As it happens, the scanl template does not use any other template from FXSL.
Here's its code:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xsl ext"
>
  <xsl:template name="scanl">
    <xsl:param name="pFun" select="/.."/>
    <xsl:param name="pQ0" select="/.."/>
    <xsl:param name="pList" select="/.."/>
    <xsl:param name="pElName" select="'el'"/>
    <xsl:param name="pStarting" select="1"/>

    <xsl:variable name="vLength" select="count($pList)"/>

    <xsl:choose>
      <xsl:when test="$vLength > 1">
        <xsl:variable name="vHalf" select="floor($vLength div 2)"/>

        <xsl:variable name="vrtfResult1">
        <xsl:call-template name="scanl">
        <xsl:with-param name="pFun" select="$pFun"/>
        <xsl:with-param name="pQ0" select="$pQ0" />
        <xsl:with-param name="pList" select="$pList[position() &lt;=
$vHalf]"/>
        <xsl:with-param name="pElName" select="$pElName"/>
            <xsl:with-param name="pStarting" select="$pStarting"/>
        </xsl:call-template>
       </xsl:variable>

       <xsl:variable name="vResult1" select="ext:node-set($vrtfResult1)/*"/>

       <xsl:copy-of select="$vResult1"/>

       <xsl:call-template name="scanl">
       <xsl:with-param name="pFun" select="$pFun"/>
       <xsl:with-param name="pQ0" select="$vResult1[last()]" />
       <xsl:with-param name="pList" select="$pList[position() > $vHalf]"/>
       <xsl:with-param name="pElName" select="$pElName"/>
          <xsl:with-param name="pStarting" select="0"/>
       </xsl:call-template>
      </xsl:when>

      <xsl:otherwise>
      <xsl:if test="$pStarting">
       <xsl:element name="{$pElName}">
         <xsl:copy-of select="ext:node-set($pQ0)/node()"/>
       </xsl:element>
      </xsl:if>

        <xsl:if test="$pList">
       <xsl:element name="{$pElName}">
         <xsl:apply-templates select="$pFun">
           <xsl:with-param name="pArg1" select="$pQ0"/>
           <xsl:with-param name="pArg2" select="$pList[1]"/>
         </xsl:apply-templates>
       </xsl:element>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

$pQ0 contains the initial value (often zero) for the operation and is the
result when an empty list is provided. The results are "accumulated" in
$pQ0 -- that is when the scanl template calls itself recursively, it passes
the last of all results. All intermediate results are output.

$pFun must be a template reference to a template (a node, matched by this
template) that performs the step operation.
This template must have two xsl:param children named "pArg1" and "pArg2".
pArg1 contains the (last) current accumulated result. pArg2 is the top
element of the current list.

$pList is the list of elements that must be processed.

The other parameters have default values and one should not worry (and
generally is not expected to know) about them.

This template is a little bit longer, because it implements DVC-style
recursive processing, splitting the list in two halves, processing
recursively the first half and then using the result of this first half's
processing as pQ0 for the recursive processing of the second half of the
list. This ensures that there will not be a stack overflow due to
excessively deep recursive processing.


The same in XSLT2 is implementid like this:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:f="http://fxsl.sf.net/"
 xmlns:int="http://fxsl.sf.net/dvc-scanl/int"
 exclude-result-prefixes="f int xs"
>
  <xsl:import href="func-apply.xsl"/>

  <xsl:function name="f:scanl">
    <xsl:param name="pFun" as="element()"/>
    <xsl:param name="pQ0"/>
    <xsl:param name="pList" as="item()*"/>

    <xsl:sequence select="int:scanl($pFun, $pQ0, $pList, 1)"/>
  </xsl:function>

  <xsl:function name="int:scanl">
    <xsl:param name="pFun" as="element()"/>
    <xsl:param name="pQ0"/>
    <xsl:param name="pList" as="item()*"/>
    <xsl:param name="pStarting" as="xs:integer"/>

    <xsl:variable name="vLength" select="count($pList)"/>

    <xsl:choose>
      <xsl:when test="$vLength > 1">
        <xsl:variable name="vHalf" select="floor($vLength div 2)"/>

        <xsl:variable name="vResult1"
           select="int:scanl($pFun,
                             $pQ0,
                             $pList[position() &lt;= $vHalf],
                             $pStarting
                             )"/>
       <xsl:sequence select=
         "($vResult1,
           int:scanl($pFun,
                     $vResult1[last()],
                     $pList[position() > $vHalf],
                     0)
          )"
         />
      </xsl:when>

      <xsl:otherwise>
      <xsl:if test="$pStarting">
       <xsl:sequence select="$pQ0"/>
      </xsl:if>

        <xsl:if test="$pList">
          <xsl:sequence select="f:apply($pFun, $pQ0, $pList[1])"/>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>
</xsl:stylesheet>

Here the apply() function has the following code:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:f="http://fxsl.sf.net/"
 exclude-result-prefixes="f"
>

  <xsl:function name="f:apply">
   <xsl:param name="pFunc" as="element()"/>
   <xsl:param name="arg1"/>

    <xsl:apply-templates select="$pFunc">
      <xsl:with-param name="arg1" select="$arg1"/>
    </xsl:apply-templates>
  </xsl:function>

  <xsl:function name="f:apply">
   <xsl:param name="pFunc" as="element()"/>
   <xsl:param name="arg1"/>
   <xsl:param name="arg2"/>

    <xsl:apply-templates select="$pFunc">
      <xsl:with-param name="arg1" select="$arg1"/>
      <xsl:with-param name="arg2" select="$arg2"/>
    </xsl:apply-templates>
  </xsl:function>


  <xsl:function name="f:apply">
   <xsl:param name="pFunc" as="element()"/>
   <xsl:param name="arg1"/>
   <xsl:param name="arg2"/>
   <xsl:param name="arg3"/>

    <xsl:apply-templates select="$pFunc">
      <xsl:with-param name="arg1" select="$arg1"/>
      <xsl:with-param name="arg2" select="$arg2"/>
      <xsl:with-param name="arg3" select="$arg3"/>
    </xsl:apply-templates>
  </xsl:function>

<!-- Etc. All function definitions untill defined for up to ten
arguments -->

</xsl:stylesheet>


I would be glad to answer any further questions you might have.


=====
Cheers,

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


"Ficke, Bill" <Bill.Ficke@xxxxxxxxxxxxxxxx> wrote in message
news:92EFB80E551BD511B39500D0B7B0CDCC0A993F90@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Dimitre,
>
> Thank you for helping me.  I am sorry for not removed excess code from my
> stylesheet.  I thought you were asking for more xml, not less xsl.
>
> I have examined your example code provided in your last email, and it
> appears that my code is structured very similarly to it.  It is difficult
> for me to see where and how the running total is stored during execution.
>
> I'm assuming that downloading fxsl, I'll be able to see the templates
scan1
> and scanl1 referred to below.  Is that true?  I really need a working
> example to understand how to apply it to my situation.
>
> Thank you again for patiently working with me.
>
> Bill




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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.