This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Re: max of sum
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Fri, 1 Feb 2002 01:28:45 -0800 (PST)
- Subject: [xsl] Re: Re: max of sum
- Reply-to: xsl-list at lists dot mulberrytech dot com
> > Is there a way to get the max for a bunch of sum on an attribute.
>
> Yes, of course.
>
> > I have the following XML and would like to find what's the highest
expenses
> > (sum of all expense/@value). Which would be 303 .
> > any idea ?
> >
> > <company>
> > <department id="IT">
> > <expense value="10"/>
> > <expense value="12"/>
> > <expense value="13"/>
> > <expense value="18"/>
> > <expense value="28"/>
> > </department>
> >
> > <department id="Research">
> > <expense value="40"/>
> > <expense value="150"/>
> > <expense value="75"/>
> > <expense value="17"/>
> > <expense value="21"/>
> > </department>
> >
> > <department id="Finance">
> > <expense value="34"/>
> > <expense value="77"/>
> > </department>
> >
> > <department id="HR">
> > <expense value="22"/>
> > </department>
> > </company>
>
>
> <xsl:template match="department">
> <xsl:variable name="sum" select="sum(expense/@value)" />
> <xsl:if test="not(../department[sum(expense/@value) > $sum])">
> <xsl:text />max: <xsl:value-of select="$sum" /> for <xsl:text />
> <xsl:value-of select="@id" />
> </xsl:if>
> </xsl:template>
This above solution will calculate the sum of expenses for each
department N times (where N is the number of the department elements).
Here's a functional solution:
<xsl:stylesheet version = "1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:test-map-sum="test-map-sum"
exclude-result-prefixes = "xsl test-map-sum" >
<xsl:import href = "sum.xsl" />
<xsl:import href = "map.xsl" />
<xsl:import href = "maximum.xsl" />
<test-map-sum:test-map-sum/>
<xsl:output method = "text" />
<xsl:template match = "/" >
<!-- Get: map sum department (expense/@value) -->
<xsl:variable name = "vdeptSums" >
<xsl:variable name = "vTestMap"
select = "document('')/*/test-map-sum:*[1]" />
<xsl:call-template name = "map" >
<xsl:with-param name = "pFun" select = "$vTestMap" />
<xsl:with-param name = "pList1"
select = "/company/department" />
</xsl:call-template>
</xsl:variable>
<!-- Get maximum map sum department (expense/@value) -->
<xsl:call-template name = "maximum" >
<xsl:with-param name = "pList"
select = "msxsl:node-set($vdeptSums)/*" />
</xsl:call-template>
</xsl:template>
<xsl:template name = "makeSum" match = "test-map-sum:*" >
<xsl:param name = "arg1" />
<xsl:call-template name = "sum" >
<xsl:with-param name = "pList" select = "$arg1/*/@value" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
When applied to the given source xml document, it produces the correct
result: 303.
In the same way one can calculate the sum of products, product of sums,
... etc., which seems to be difficult to achieve in XPath 2.0.
Cheers,
Dimitre Novatchev.
__________________________________________________
Do You Yahoo!?
Great stuff seeking new owners in Yahoo! Auctions!
http://auctions.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list