Xquery,检查序列成员资格

时间:2013-08-06 10:59:54

标签: xquery sequence

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

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

返回

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

指向:

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

这里的语法是什么?

2 个答案:

答案 0 :(得分:2)

text()视为等同于字符串并不是一个好习惯。它们不是字符串,它们是以字符串形式化的节点。将它们视为同样可以导致细微的,难以诊断的错误。这是一个更好的表述:

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

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

话虽如此,因为text()节点作为字符串雾化,元素作为子节点的连接值进行雾化,通常(当元素具有简单的文本内容时)只需将元素与字符串(或序列)进行比较字符串):

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

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

另一个好的做法是尽可能将选择标准放在for表达式中,而不是放在where子句中。这通常会使意图更加清晰,但更重要的是,它还可以使处理器更容易进行优化。例如

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

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

这不仅更简单,更具表现力,像MarkLogic这样的处理器可以将collection('mycollection')[Id = $s]转换为高效的xdml:element-value-query。使用where表单可能会导致对集合中每个文档进行强力检查。

答案 1 :(得分:0)

应使用=运算符。

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

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