Subject: Re: [xsl] question about position() From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Thu, 17 May 2001 14:51:59 +0100 |
Hi Denis, > If I have understand correctly, function position() should return > position in current context, and for-each example is OK, but I don't > understand why is output from example with apply-templates > different. The xsl:apply-templates itself doesn't change the context in which something is evaluated. When you do: > <xsl:template match="/"> > <xsl:apply-templates select="r/a"> > <xsl:sort data-type="number" select="@at"/> > <xsl:with-param name="p" select="position()"/> > </xsl:apply-templates> > </xsl:template> The call to position() is being evaluated with the context node being the current node in the template itself, i.e. the *root node*. It's just as if you did: <xsl:template match="/"> <xsl:variable name="p" select="position()" /> <xsl:apply-templates select="r/a"> <xsl:sort data-type="number" select="@at" /> <xsl:with-param name="p" select="$p" /> </xsl:apply-templates> </xsl:template> On the other hand, xsl:for-each *does* change the current node, to the node that you're looking at within the current run of the loop. In the second version of the template: > <xsl:template match="/"> > <xsl:for-each select="r/a"> > <xsl:sort data-type="number" select="@at"/> > <xsl:apply-templates select="."> > <xsl:with-param name="p" select="position()"/> > </xsl:apply-templates> > </xsl:for-each> > </xsl:template> The xsl:for-each iterates over each of the a elements. Within that xsl:for-each, the current node is an a element. Evaluating *its* position() within the current node list gives its position. Again, the expressions in the xsl:with-param are just as if it was evaluated outside the xsl:apply-templates - the xsl:apply-templates doesn't change the current node, so the above is equivalent to: <xsl:template match="/"> <xsl:for-each select="r/a"> <xsl:sort data-type="number" select="@at" /> <xsl:variable name="p" select="position()" /> <xsl:apply-templates select="."> <xsl:with-param name="p" select="$p" /> </xsl:apply-templates> </xsl:for-each> </xsl:template> The simplest thing to achieve the count that you want is not to bother with parameters at all... just do: <xsl:template match="/"> <xsl:apply-templates select="r/a"> <xsl:sort data-type="number" select="@at" /> </xsl:apply-templates> </xsl:template> <xsl:template match="a"> <xsl:value-of select="position()" />,<xsl:text /> </xsl:template> Or: <xsl:template match="/"> <xsl:for-each select="r/a"> <xsl:sort data-type="number" select="@at" /> <xsl:value-of select="position()" />,<xsl:text /> </xsl:for-each> </xsl:template> I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] question about position(), Denis Kranjcec | Thread | Re: [xsl] question about position(), Oliver Becker |
Re: [xsl] Variables, Jeni Tennison | Date | Re: [xsl] Two input xml files.., Jeni Tennison |
Month |