[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: question about position()
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
|
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
|