An Aside: Doing Math with Recursion

While we’re here, we’ll also mention the recursive technique we used to calculate the total for each purchase order. At first glance, this seems like a perfect opportunity to use the sum() function. We want to add the total of the price of each item multiplied by its quantity. We could try to invoke the sum() function like this:

<xsl:value-of select="sum(item/qty*item/price)"/>

Unfortunately, the sum() function simply takes the node-set passed to it, converts each item in the node-set to a number, and then returns the sum of all of those numbers. The expression item/qty*item/price, while a perfectly valid XPath expression, isn’t a valid node-set. With that in mind, we have to create a recursive <xsl:template> to do the work for us. There are a couple of techniques worth mentioning here; we’ll go through them in the order we used them in our stylesheet.

[2.0] If you’re using an XSLT 2.0 processor, you can use new functions of XPath 2.0 to avoid recursion altogether. XSLT 2.0 makes this stylesheet much simpler and shorter; we discuss all the details in the last section of this chapter. If you’re using an XSLT 2.0 processor and you don’t really care how recursion works, feel free to skip ahead.

Recursive design

First, we pass the set of all <items> elements to our recursive template:

<xsl:variable name="orderTotal">
  <xsl:call-template name="sumItems">
    <xsl:with-param name="items" select="items/item" />
  </xsl:call-template>      
</xsl:variable>

Our recursive ...

Get XSLT, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.