[xquery-talk] some ... satisfies with positional variable

Michael Kay mhk at mhk.me.uk
Sat Aug 20 08:58:21 PDT 2005

> Here's a question about an XQuery language construct I would 
> appreciate.

You seem to be overlooking that XQuery has XPath as a subset. These queries
can all be expressed by simple and efficient XPath 1.0 expressions.

> in for-clauses it is possible to include a positional 
> variable and return
> the context node $fs:dot - or any other node - based on the 
> position of
> its child elements.
> for $x at $pos in child::tag0 return
>     if ($pos > 3) then return $fs:dot

> If the context node has more than 4 children, the above 
> expression will
> return it more than once. This could be avoided by wrapping 
> the result in
> a distinct-doc-order function, but it wouldn't prevent the 
> compiler from
> executing extra work, does it?

You seem to be searching for the expression


(The parentheses are needed in XPath 1.0 but not in XPath 2.0)

Any decent XPath processor is going to execute this very efficiently.

> Without positional variables extra work can be evaded by 
> using the some
> ... satisfies ... clause:
> if (some $x in child::* satisfies (fn:node-name($x) == "tag2")))
> then $fs:dot
> else ()

Actually, you want "=" or "eq" rather than "=="; and node-name() returns a
QName not a string. Rather than getting a node-name as a run-time string or
QName, it's better to do ($x[self::tag2]).

> This works fine, but I cannot include a positional variable in the
> conditional. What I need is a "some ... at ... in ... satisfies ... "
> construct similar to the following:
> epxr1 =
> if (some $x at $pos in child::* satisfies ($pos > 3))
> then $fs:dot
> else ()

Again, you're forgetting positional predicates: you can write this as

if (child::*[position() gt 3])

or more simply

if (*[4]) then . else ()

or just


> But this is not provided by XQuery. XPath expressions won't help since
> they're normalized to for, if-clauses, etc.

That's an odd way of looking at the world: XPath expressions like the ones
above have been around since 1999, long before for expressions and if
clauses were invented.

Michael Kay

More information about the talk mailing list