O'Reilly logo

XSLT, 2nd Edition by Doug Tidwell

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

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

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required