This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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@elastica.com 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]