Re: Understanding difficulties with call-template
OK got it working here this works. <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> <xsl:template match="preferred-locations"> <xsl:element name="p"> Preferred Locations: <xsl:call-template name="comma-block"> <xsl:with-param name="nodes" select="preferred-location"/> </xsl:call-template> </xsl:element> </xsl:template> On Wed, 25 Oct 2000, Mike Brown wrote: > 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
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format