As a next attempt, we'll declare a variable to accumulate and hold the extended price. Then we'll try to use that variable for the sum operation. The style sheet now looks like this:
<xsl:variable name="ext_price">
<xsl:for-each select="invoice/item">
<accum><xsl:value-of select="quantity * unit_price"/></accum>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
...
<tr>
<th colspan="3">Total, All Items</th>
<td align="right">
<xsl:value-of select="format-number(sum($ext_price/accum), '#,##0.00')"/>
</td>
</tr>
...
The result of this attempt is shown in the following example.
XML File (invoice.xml)
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="inv3.xsl" ?>
<invoice>
<item item_num="AX43598">
<quantity>29</quantity>
<unit_price>2.00</unit_price>
</item>
<item item_num="FH29782">
<quantity>140</quantity>
<unit_price>6.50</unit_price>
</item>
</invoice>
XSLT File (inv3.xsl)
<?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:variable name="ext_price"><xsl:for-each select="invoice/item"><accum><xsl:value-of select="quantity * unit_price"/></accum></xsl:for-each></xsl:variable><xsl:template match="/"> <table border="1" cellpadding="2" cellspacing="0"> <tr> <th>Item</th> <th>Quantity</th> <th>Unit Price</th> <th>Extended Price</th> </tr> <xsl:for-each select="invoice/item"> <tr> <td> <xsl:value-of select="@item_num"/> </td> <td align="right"> <xsl:value-of select="quantity"/></td> <td align="right"> <xsl:value-of select="format-number(unit_price, '#,##0.00')"/> </td> <td align="right"> <xsl:value-of select="format-number(quantity * unit_price, '#,##0.00')"/> </td> </tr> </xsl:for-each><tr><th colspan="3">Total, All Items</th><td align="right"><xsl:value-of select="format-number(sum($ext_price/accum), '#,##0.00')"/></td></tr></table> </xsl:template> </xsl:stylesheet>
Result
Now when we try to view our sample document in Internet Explorer, we get another error message:
Reference to variable or parameter 'ext_price' must evaluate to a node list.
Even though the <accum> element contains numeric data, the XPath sum() function must take a node-set as an argument. To correct the problem, see the next topic, Calculating a Sum of Sums (Final Version).