xquery匹配-允许循环中不存在的节点



我有一个for循环,想要过滤一些节点,这很好:

matches($doc/abc/@def, $filterA)
matches($doc/qwert/@xyz, $filterB)

同样有效的是,当$filterA$filterB或两者都为空时,返回每个节点。但是,如果节点abcqwert不存在,则返回节点是不起作用的。对于我当前使用的默认值""(空字符串(,是否有其他默认值或其他函数可以用于使其工作?

使用fn:exists()函数可以测试abcqwert元素是否存在。如果你想让它通过,如果这两个元素中的任何一个都不存在,你可以使用fn:not()来否定abcqwert存在的测试:

fn:not(fn:exists($doc/abc) and fn:exists($doc/qwert))

如果您想在$filterA$filterB为空时通过条件:

fn:not(fn:exists($filterA) and fn:exists($filterB)) 

您可以将matches()表达式合并为一个谓词,以避免重复$doc(这不是一个巨大的节省,但在编写XPath表达式时需要更广泛地考虑

$doc[matches(abc/@def, $filterA) and matches(qwert/@xyz, $filterB)] 

综合起来:

let $filterA := "a"
let $filterB :="b"
let $doc := <doc><abc def="a"/><qwert xyz="b"/></doc>
return
if (fn:not(fn:exists($doc/abc) and fn:exists($doc/qwert))
or fn:not(fn:exists($filterA) and fn:exists($filterB)) 
or $doc[matches(abc/@def, $filterA) and matches(qwert/@xyz, $filterB)])
then "pass - copy nodes"
else "fail"

最新更新