« Concurrent calls to the same session object not allowed | Main | Happy Halloween »
XSLT: Sum of products from multiple nodes
October 31, 2003Keywords:
The XSL method sum(/foo) sums the value of all foo nodes in current context. If you, however, want to sum the product between two or more nodes the sum(/foo * /bar) is not sufficient as the product does not return a nodeset and thus sum() fails.
I found one way to sum products of multiple nodes and is to construct a temporary variable with the products, convert that variable to a nodeset and the sum all nodes in that temporary node set.
The function that converts a variable to a nodeset seems to be XSLT specific and the solution below is for Xalan since we are using it in our app. If you are using MSXML you will have to change the namespace but the name of the function is the same.
XML:
<Order>
<OrderLine>
<Quantity>
<Amount>2</Amount>
</Quantity>
<Price>
<UnitPrice>25</UnitPrice>
</Price>
</OrderLine>
<OrderLine>
<Quantity>
<Amount>10</Amount>
</Quantity>
<Price>
<UnitPrice>2</UnitPrice>
</Price>
</OrderLine>
<OrderLine>
<Quantity>
<Amount>23</Amount>
</Quantity>
<Price>
<UnitPrice>6</UnitPrice>
</Price>
</OrderLine>
</Order>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:template match="/Order">
<root>
<xsl:variable name="tmpTotal">
<total_amount>
<xsl:for-each select="OrderLine">
<item>
<xsl:value-of select="Quantity/Amount * Price/UnitPrice"/>
</item>
</xsl:for-each>
</total_amount>
</xsl:variable>
<total>
<xsl:variable name="myTotal" select="xalan:nodeset($tmpTotal)"/>
<xsl:value-of select="sum($myTotal/total_amount/item)" />
</total>
</root>
</xsl:template>
</xsl:stylesheet>
Trackback Pings
TrackBack URL for this entry:
http://blog.davidkaspar.com/cgi-bin/fsdg39fmcnswgv.cgi/72





rohit mathur Says:
May 29, 2004 01:05 PM
thanx
this came in really handy
will definitely use it...
thank you Says:
October 16, 2004 01:24 PM
very accurate and helpful
Bruno Says:
April 18, 2007 08:14 AM
Note to make it work with .NET XslTransform. You have to use the msxsl:node-set() function:
<xsl:value-of select="sum( msxsl:node-set($myTotal)/total_amount/item )" />
Oh, and to have access to that function, add this namespace to your XSLT tag:
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
goku Says:
June 14, 2007 10:47 PM
it was very useful.
Thank you very much.