Computing Sums and Products
Problem
You need to sum or multiply functions of numbers contained in a node set.
Solution
The abstract form of sum for processors that support tail-recursive optimization is as follows:
<xsl:template name="math:sum"> <!-- Initialize nodes to empty node set --> <xsl:param name="nodes" select="/.."/> <xsl:param name="result" select="0"/> <xsl:choose> <xsl:when test="not($nodes)"> <xsl:value-of select="$result"/> </xsl:when> <xsl:otherwise> <!-- call or apply template that will determine value of node unless the node is literally the value to be summed --> <xsl:variable name="value"> <xsl:call-template name="some-function-of-a-node"> <xsl:with-param name="node" select="$nodes[1]"/> </xsl:call-template> </xsl:variable> <!-- recurse to sum rest --> <xsl:call-template name="math:sum"> <xsl:with-param name="nodes" select="$nodes[position( ) != 1]"/> <xsl:with-param name="result" select="$result + $value"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>
Two techniques can handle a large number of nodes in the absence of
tail-recursive optimization. The first is commonly called
divide and conquer
.
The idea behind this technique is to
reduce the amount of work by at least a factor of two on each
recursive step:
<xsl:template name="math:sum-dvc"> <xsl:param name="nodes" select="/.."/> <xsl:param name="result" select="0"/> <xsl:param name="dvc-threshold" select="100"/> <xsl:choose> <xsl:when test="count($nodes) <= $dvc-threshold"> <xsl:call-template ...
Get XSLT Cookbook 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.