|
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 |