Subject: Re: Understanding difficulties with call-template From: Mike Brown <mike@xxxxxxxx> Date: Wed, 25 Oct 2000 17:50:14 -0600 (MDT) |
robert@xxxxxxxxxxxx wrote: > I have the following code > > <xsl:template name="comma-block"> > <xsl:for-each select="."> > <xsl:value-of select="."/> > <xsl:if test="not(position()=last())">, </xsl:if> > </xsl:for-each> > </xsl:template> > > <xsl:template match="preferred-locations"> > <xsl:element name="p"> > Preferred Locations: > <xsl:call-template name="comma-block"/> > </xsl:element> > </xsl:template> > > now when I call the template it correct outputs the correct nodes but > the xsl:if test doesn't work .... position==last for all nodes. > > When I inline the above code instead of using call-template the > xsl:if test works as expected. You are probably assuming that the current node list is defined by the template match pattern. Sections 1 (starting around "A template is instantiated for...") and 5.1 (one paragraph) of the XSLT spec explain the actual processing model. The node-set that has been selected for processing is the current node list. There is always a current node list, and from that list there is always a current node being processed. You don't have direct access to the list, but you can get some information about it via functions like position(), last(), and count(). You do have access to the current node ('.' in your patterns and expressions). The current node list starts out as being just the root node. The best matching template for that node is instantiated, and processing ends. For further node processing to occur, the template must contain an xsl:apply-templates or xsl:for-each instruction, either of which will select a new set of nodes for processing. In the case of apply-templates, the best matching template for each node is determined, and the instructions therein are executed. In the case of for-each, the content of the for-each element is the template used for each node. Each selected node is processed one by one, each becoming the current node while the best template is instantiated, and the current node list staying the same (the set that was originally selected). When you do a call-template, variables from the calling-template go out of scope, but the current node and current node list stay the same. Somehow you are getting to a point where you have at least one preferred-locations element being processed. How are you getting there? Elsehwere in your stylesheet there must be an xsl:apply-templates that is selecting preferred-locations elements. It is there that the current node list is being established. It is relative to this list that position() and last() will operate outside of that xsl:for-each in your named template. Inside the xsl:for-each, you've resent the current node list to the current node only, so position() and last() are both going to be 1 no matter how many times you call that template. At the point where you are selecting the preferred-locations elements for processing, you'll want to put <xsl:element name="p"> <xsl:text>Preferred Locations: </xsl:text> <xsl:call-template name="comma-block"> <xsl:with-param name="nodes" select="preferred-locations"/> </xsl:call-template> </xsl:element> and then have <xsl:template name="comma-block"> <xsl:param name="nodes"/> <xsl:for-each select="$nodes"> <xsl:value-of select="."/> <xsl:if test="position() != last()">, </xsl:if> </xsl:for-each> </xsl:template> There is no need for a template to match the preferred-locations elements because you're using the contents of the for-each as the template for them. - Mike ____________________________________________________________________ Mike J. Brown, software engineer at My XML/XSL resources: webb.net in Denver, Colorado, USA http://www.skew.org/xml/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Understanding difficulties with cal, robert | Thread | Re: Understanding difficulties with, robert |
Understanding difficulties with cal, robert | Date | Re: .. and parent::node(), Alex Albu |
Month |