RE: [xsl] Trying to undestand why template works

Subject: RE: [xsl] Trying to undestand why template works
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 24 Feb 2006 00:23:35 -0000
> After some digging and experimenting, I finally got a stylesheet to 
> do what I wanted. Among other things, it uses the template below. 
> Problem is, I don't really understand WHY this template works, and 
> would very much like to.

It's a classic example of head-tail recursion. The general form of this is
"process the first node; call yourself to process the rest of the sequence;
combine the results". For example, the value of an expression summed over a
sequence is the value of the expression applied to the first item in the
sequence plus the result of calling yourself to process the rest of the
sequence. 

<xsl:param name="node"/> 
  is misnamed: the parameter is actually a sequence of nodes.

<xsl:param name="hourVal"/> 
  this is the total so far

<xsl:when test="$node"> 
  says: when you're called with an empty sequence of nodes, terminate the
recursion

<xsl:call-template name="sum-value">
 	<xsl:with-param name="node" select="$node[position() &gt; 1]"/>
      <xsl:with-param name="hourVal" select="$hourVal"/>
</xsl:call-template>
  is the recursive call: the node parameter contains all nodes in the input
list except the first

<xsl:value-of select="$recursive_result + number($node[1]/@time *
$hourVal)"/>
  does the computation for the first node and adds the result of the
recursive call

Michael Kay
http://www.saxonica.com/


> 
> Here's the template:
> 
> <xsl:template name="sum-value">
> 	<xsl:param name="node"/>
> 	<xsl:param name="hourVal"/>
> 	<xsl:choose>
> 		<xsl:when test="$node">
> 			<xsl:variable name="recursive_result">
> 				<xsl:call-template name="sum-value">
> 					<xsl:with-param 
> name="node" select="$node[position() &gt; 1]"/>
> 					<xsl:with-param 
> name="hourVal" select="$hourVal"/>
> 				</xsl:call-template>
> 			</xsl:variable>
> 		<xsl:value-of select="$recursive_result + 
> number($node[1]/@time * 
> $hourVal)"/>
> 		</xsl:when>
> 		<xsl:otherwise>
> 			<xsl:value-of select="0"/>
> 		</xsl:otherwise>
> 	</xsl:choose>
> </xsl:template>
> 
> I just don't understand how the select="$node[position() &gt; 1]" bit 
> works. I assume that with each recursion this is selecting the next 
> child of the input node (param "node"), but have no idea how or why. 
> 
> Doesn't "position() &gt; 1" evaluate to either 0 or 1? If so, where 
> is the input node becoming the next child of the original input node 
> (at the first level of the recursion)? Or, if my question doesn't 
> make any sense, how the heck is the recursion moving on to the next 
> child of the input node in order to add them all up?
> 
> Thanks in advance to anyone who can shed any light on this issue.
> 
> Erik
> 
> 		
> _______________________________________________________
> Yahoo! Acesso Gratis - Internet rapida e gratis. Instale o 
> discador agora!
> http://br.acesso.yahoo.com

Current Thread