Re: [xsl] sum() with selective attribute

Subject: Re: [xsl] sum() with selective attribute
From: Mike Brown <mike@xxxxxxxx>
Date: Mon, 6 Jan 2003 15:36:58 -0700 (MST)
Lee, Insoo wrote:
> 
>  Hi,  how would I use sum() function along with attribute?
>   for the given xml shown below, I would get a grand total per each
> currency...
>   I guess I can do something like
> sum(/REPORT/ENTITY/FUND_GROUP/ROW/SOME_VALUE) along with "xsl:if", but I'd
> like to avoid scanning through the tree again looking up CURRENCY
> attribute... any suggestion?
>   Thanks
> 
> 
> <REPORT>
>     <ENTITY NUMBER="1">
>         <FUND_GROUP CURRENCY="GBP">
>             <ROW>
>                 <SOME_VALUE>100</SOME_VALUE>
>             </ROW>
> [...]

This is a grouping problem. There are many examples in the FAQ and on Jeni's
site. 

First you need to identify one of each unique CURRENCY attribute. The
not-very-efficient but easiest-to-understand way is to narrow down the set of
all CURRENCY attributes to just those for which there are no preceding
CURRENCY attributes with the same value.

Then, getting the sum total of all the SOME_VALUEs that fall under the current
CURRENCY is fairly straightforward.

<xsl:for-each select="/REPORT/ENTITY/FUND_GROUP/@CURRENCY[not(.=preceding::FUND_GROUP/@CURRENCY)]">
  <xsl:value-of select="concat(.,':',sum(/REPORT/ENTITY/FUND_GROUP[@CURRENCY=current()]/ROW/SOME_VALUE))"/>
</xsl:for-each>

There's a better way to get the sum, though. Set up this key beforehand:

<xsl:key name="values-by-currency" match="SOME_VALUE" use="../../FUND_GROUP/@CURRENCY"/>

Now you can use sum(key('values-by-currency',current())) in the xsl:value-of
above.

The for-each can also be optimized with keys. See
http://www.jenitennison.com/xslt/grouping/muenchian.html
for a thorough explanation.

Mike

-- 
  Mike J. Brown   |  http://skew.org/~mike/resume/
  Denver, CO, USA |  http://skew.org/xml/

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


Current Thread