Calculating a Sum of Sums (Second Attempt)

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Calculating a Sum of Sums (Second Attempt)

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.

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).