Re: [xsl] Unexpected ('a', 'b')[fn:position()] result

Subject: Re: [xsl] Unexpected ('a', 'b')[fn:position()] result
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Wed, 07 Mar 2007 01:12:41 +0100
Rachel D. Basse wrote:
<xsl:template match="/">
 <xsl:sequence select="('a', 'b')[fn:position()]"/>
</xsl:template>

returns ('a', 'b').

Why is this? Everything tells me the last expression should evaluate to 'a'. Did I miss something?

Hi Rachel,


It's a classic, and every now and then, I do it wrongly still (check the archives, I have once or twice asked about the same question). The function position() (you don't need to put "fn:" in front of it) returns the position of the context node. The context changes within the XPath expression to each node it is evaluating.

Thus, the expression

('a', 'b')[position()]

a) will test the first item in the sequence 'a' for the predicate [position()] which evaluates to the predicate [1], which is short for [position() = 1], which will return true because the current position is 1.

b) will test the second item in the sequence 'b' for the predicate [position()] which evaluates to the predicate [2], which is short for [position() = 2], which will return true because the current position is 2 (we are at the second item, 'b', remember).

As it comes, the following:

some-node[position()]

will always evaluate to true, and

(some-sequence)[position()]

will always return the whole sequence, because each separate item will always have the position in the sequence that equals the result of the predicate [position()].

What you want is the following:

<xsl:variable name="pos" select="position()" />
<xsl:sequence select="('a', 'b')[$pos]" />

HTH,

Cheers,
-- Abel Braaksma
  http://www.nuntia.nl

Current Thread