Subject: [xsl] 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 |
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() <= $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() <= $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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Re: Re: How to Calculate , Ficke, Bill | Thread | [xsl] Omitting node within For-Each, JCS |
RE: [xsl] Too slow to process XML f, Todd Baker | Date | [xsl] Re: Omitting node within For-, Dimitre Novatchev |
Month |