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

Re: Calculate balance

Subject: Re: Calculate balance
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Mon, 11 Mar 2002 11:33:06 -0800 (PST)
free ledgerbook software
Using the scanl1 function from the functional programming library FXSL,
the solution to the problem is quite easy:

The following stylesheet:

runningBalance.xsl:
------------------
<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:funTypedSum="f:funTypedSum" 
 exclude-result-prefixes="xsl funTypedSum"
 >
  <xsl:import href="Fxsl\Msxsl\scanl.xsl"/>
  
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  
  <funTypedSum:funTypedSum/>
  
  <xsl:template match="/">
    <xsl:variable name="vTypedSum" 
                  select="document('')/*/funTypedSum:*[1]"/>
    <xsl:variable name="vList" 
            select="/report/ledgerbook/table/row/amount"/>
            
    <xsl:variable name="vOpeningBalance" 
                  select="/report/ledgerbook/openingbalance"/>
    
    <xsl:call-template name="scanl">
      <xsl:with-param name="pFun" select="$vTypedSum"/>
      <xsl:with-param name="pQ0" select="$vOpeningBalance"/>
      <xsl:with-param name="pList" select="$vList"/>
      <xsl:with-param name="pElName" select="'balance'"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template match="funTypedSum:*">
    <xsl:param name="pArg1"/>
    <xsl:param name="pArg2" select="/.."/>
    
    <xsl:variable name="vThisAmount" 
            select="$pArg2 * ((($pArg2/@type = 'C') * 2) - 1)"/>
    
    <xsl:value-of select="$pArg1 + $vThisAmount"/>
  </xsl:template>
</xsl:stylesheet>

when applied on the original xml source document:

runningBalance.xml:
------------------
<report>
  <date>
    <currentdate>11-Mar-2002</currentdate>
    <startdate>12-dec-02</startdate>
    <enddate>12-dec-02</enddate>
  </date>

  <ledgerbook>
    <openingbalance>-2000.0</openingbalance>

    <table>
      <row>
        <ledgerdate>12-DEC-2002</ledgerdate>
        <voucher>V1.1.3</voucher>
        <costcenter>Head Office</costcenter>
        <lccode />
        <description />
        <amount type="C">1000</amount>
      </row>

      <row>
        <ledgerdate>12-DEC-2002</ledgerdate>
        <voucher>V1.1.2</voucher>
        <costcenter>Head Office</costcenter>
        <lccode />
        <description />
        <amount type="C">1000</amount>
      </row>

      <row>
        <ledgerdate>12-DEC-2002</ledgerdate>
        <voucher>V1.2.1</voucher>
        <costcenter />
        <lccode />
        <description />
        <amount type="D">2000</amount>
      </row>

      <row>
        <ledgerdate>12-DEC-2002</ledgerdate>
        <voucher>V1.2.2</voucher>
        <costcenter />
        <lccode />
        <description />
        <amount type="D">2000</amount>
      </row>
    </table>
  </ledgerbook>
</report>



Produces this result:

<balance>-2000.0</balance>
<balance>-1000</balance>
<balance>0</balance>
<balance>-2000</balance>
<balance>-4000</balance>


Hope this helped.

Cheers,
Dimitre Novatchev.

Jeni Tennison <jeni at jenitennison dot com> wrote:

> Hi Shabbir,
> 
> >> Or if performance is really an issue, you could take a different
> >> approach in which you step through the rows one by one, with a
> >> template that applies templates to the next row and passes on the
> >> balance from each step. Let us know if you want to see an example
> >> of how that would work.
> >
> > Yes, I want to know that approch.
> 
> OK. Currently, you tell the processor to iterate over all the rows at
> once, with an xsl:for-each:
> 
>   <xsl:for-each select="report/ledgerbook/table/row">
>     <tr>
>       <td><xsl:value-of select="ledgerdate"/></td>
>       <td><xsl:value-of select="voucher"/></td>
>       <td><xsl:value-of select="costcenter"/></td>
>       <td><xsl:value-of select="lccode"/></td>
>       <td><xsl:value-of select="description"/></td>
>       <xsl:call-template name="amountplace"/>
>     </tr>
>   </xsl:for-each>
> 
> Rather than do that, you can manually step through them one by one.
> This enables you to pass parameters, keeping track of the current
> balance, from one row to the next.
> 
> Instead of the xsl:for-each, then, just apply templates to the first
> row in your table:
> 
>   <xsl:apply-templates select="report/ledgerbook/table/row[1]" />
> 
> Then create a template that matches row elements and takes a
> parameter, $balance, which is originally set to the openingbalance:
> 
> <xsl:template match="row">
>   <xsl:param name="balance" select="../../openingbalance" />
>   ...
> </xsl:template>
> 
> Within the template, you can work out the difference between this
> balance and the previous one as I showed in the last email, and
> therefore work out a new balance based on the old one:
> 
> <xsl:template match="row">
>   <xsl:param name="balance" select="../../openingbalance" />
>   <xsl:variable name="difference">
>     <xsl:choose>
>       <xsl:when test="amount/@type = 'D'">
>         <xsl:value-of select="amount * -1" />
>       </xsl:when>
>       <xsl:otherwise>
>         <xsl:value-of select="amount" />
>       </xsl:otherwise>
>     </xsl:choose>
>   </xsl:variable>
>   <xsl:variable name="newbalance" select="$balance + $difference" />
>   ...
> </xsl:template>
> 
> You can use this new balance within the tr element that you
> create:
> 
> <xsl:template match="row">
>   <xsl:param name="balance" select="../../openingbalance" />
>   <xsl:variable name="difference">
>     <xsl:choose>
>       <xsl:when test="amount/@type = 'D'">
>         <xsl:value-of select="amount * -1" />
>       </xsl:when>
>       <xsl:otherwise>
>         <xsl:value-of select="amount" />
>       </xsl:otherwise>
>     </xsl:choose>
>   </xsl:variable>
>   <xsl:variable name="newbalance" select="$balance + $difference" />
>   <tr>
>     <td><xsl:value-of select="ledgerdate"/></td>
>     <td><xsl:value-of select="voucher"/></td>
>     <td><xsl:value-of select="costcenter"/></td>
>     <td><xsl:value-of select="lccode"/></td>
>     <td><xsl:value-of select="description"/></td>
>     <xsl:call-template name="amountplace"/>
>     <td><xsl:value-of select="$newbalance" /></td>
>   </tr>
>   ...
> </xsl:template>
> 
> You can also use it as the value to be passed to the next row that
> you
> process. You need to apply templates to the immediately following row
> within the document, passing the value of the $newbalance variable as
> the value of the $balance parameter, as follows:
> 
> <xsl:template match="row">
>   <xsl:param name="balance" select="../../openingbalance" />
>   <xsl:variable name="difference">
>     <xsl:choose>
>       <xsl:when test="amount/@type = 'D'">
>         <xsl:value-of select="amount * -1" />
>       </xsl:when>
>       <xsl:otherwise>
>         <xsl:value-of select="amount" />
>       </xsl:otherwise>
>     </xsl:choose>
>   </xsl:variable>
>   <xsl:variable name="newbalance" select="$balance + $difference" />
>   <tr>
>     <td><xsl:value-of select="ledgerdate"/></td>
>     <td><xsl:value-of select="voucher"/></td>
>     <td><xsl:value-of select="costcenter"/></td>
>     <td><xsl:value-of select="lccode"/></td>
>     <td><xsl:value-of select="description"/></td>
>     <xsl:call-template name="amountplace"/>
>     <td><xsl:value-of select="$newbalance" /></td>
>   </tr>
>   <xsl:apply-templates select="following-sibling::row[1]">
>     <xsl:with-param name="balance" select="$newbalance" />
>   </xsl:apply-templates>
> </xsl:template>
> 
> Cheers,
> 
> Jeni
> 
> 
> 
> 
> __________________________________________________
> Do You Yahoo!?
> Try FREE Yahoo! Mail - the world's greatest free email!
> http://mail.yahoo.com/


__________________________________________________
Do You Yahoo!?
Try FREE Yahoo! Mail - the world's greatest free email!
http://mail.yahoo.com/

 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.