Ben Aston
Ben Aston

Reputation: 55739

Xquery, checking for sequence membership

let $s := ('foo', 'bar')

for $d in collection('mycollection')
where ($d/Id/text() in $s)
return <p>{$d//Name} ({$d//Id})</p>

Returns

[1.0-ml] XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected In_, expecting Comma_ or Rpar_ or SemiColon_

Pointing to:

where ($d/Id/text() in $s)

What is the correct syntax here?

Upvotes: 0

Views: 370

Answers (2)

Ron Hitchens
Ron Hitchens

Reputation: 191

It's not a good habit to think of text() as equivalent to string. They're not strings, they're nodes that atomize as strings. Treating them as the same can lead to subtle, hard to diagnose bugs. A better formulation is this:

let $s := ('foo', 'bar')

for $d in collection('mycollection')
where $d/Id/fn:string() = $s
return <p>{$d/Name} ({$d/Id})</p> 

That being said, because text() nodes atomize as strings, and elements atomize as the concatenated values of their children, you can usually (when an element has simple text content) simply compare the element to a string (or sequence of strings):

let $s := ('foo', 'bar')

for $d in collection('mycollection')
where $d/Id = $s
return <p>{$d/Name} ({$d/Id})</p> 

Another good practice is to place the selection criteria in the for expression where possible, rather than in a where clause. This often makes the intent more clear, but more importantly it can also make it easier for the processor to optimize. For example

let $s := ('foo', 'bar')

for $d in collection('mycollection')[Id = $s]
return <p>{$d/Name} ({$d/Id})</p>

This is not only simpler and more expressive, a processor like MarkLogic can convert collection('mycollection')[Id = $s] into an efficient xdml:element-value-query. Using the where form could result in a brute-force check of every document in the collection.

Upvotes: 2

Ben Aston
Ben Aston

Reputation: 55739

The = operator should be used.

let $s := ('foo', 'bar')

for $d in collection('mycollection')
where $d/Id/text() = $s
return <p>{$d/Name} ({$d/Id})</p> 

Upvotes: 0

Related Questions