[xsl] Numeric top-level predicates in patterns

Subject: [xsl] Numeric top-level predicates in patterns
From: "Abel Braaksma (Exselt)" <abel@xxxxxxxxxx>
Date: Wed, 02 Apr 2014 16:51:28 +0200
Let's first agree on some terminology, before I ask the question:

Numeric predicates
A predicate that has static numeric type, such as [3], [last()],
[+@amount], [2.3]

Positional predicates
A predicate that uses position() or last(), such as [position() > 3] and
[@pos = last()]
All numeric predicates are also positional predicates. The reverse is
not true.

Boolean predicates
Anything else. Such as [node()], [foo:bar], [3 eq xs:integer(@id)]
All positional and numerical predicates are also boolean predicates, the
reverse is not true.

Top-level predicates
A predicate that is not nested, i.e. foo[bar] has a top-level predicate

Nested predicates
A predicate that is contained within another predicate, such as
foo[bar[@id]], here [@id] is the nested predicate.

Sibling predicates
A predicate that has a preceding predicate, such as foo[a][b], here [b]
is a sibling predicate.

Apart from positional predicates, I am not sure whether any of these
have any official bearing, as in whether they are elswehere defined as such.

Now the question. After the discussion on position(), I started
wondering about patterns and position. I believe the following is all
true (assume they the patterns are placed inside <xsl:template match="XXX">.

Selects nothing, ever (not even in a select-expression):

Redundant [1], always redundant:

The rules I am after is, in this order:
1) numerical predicates lower than zero never select anything
2) a sibling numerical predicate that is one is always redundant in a
3) a sibling predicate that is a sibling of a numeric predicate that is
higher than one never selects anything

Then, to make it tricky, what happens here, if the applied set is //foo?

I did not find that well-defined in the spec or in Michael Kay's XSLT
2.0 Programmer's Reference book. The programmer's intended meaning is
"for any given foo in the selection, group the second children, take the
third". But what it does is "for any second foo, take the third". I
believe this behavior is correct (in which case nothing will ever be
selected), and the reason it is so, is because of the singleton focus on
the current item when the match pattern is applied.

The pattern, if applied as an expression in a select-statement, does
have merit though and will select the first third foo element that is
also a second child.

Bottom line is, I think, that creating multiple sibling numerical
predicates is (usually) counter-productive and won't match anything when
used in a pattern (unless the number is "1", in which case it is also

I do understand what all above patterns are supposed to do, but the
point is, is this your understanding of the spec also, and are my
"rules" correct or did I miss corner cases? I would like to hear your
(anybody's?) thoughts on this and whether I am missing something obvious
here. Are multiple sibling numerical predicates indeed useless in
(almost) all situations? Do you know of situations where it may have merit?


Abel Braaksma
Exselt XSLT 3.0 processor

Current Thread