我有一个for循环,想要过滤一些节点,这很好:
matches($doc/abc/@def, $filterA)
matches($doc/qwert/@xyz, $filterB)
同样有效的是,当$filterA
、$filterB
或两者都为空时,返回每个节点。但是,如果节点abc
或qwert
不存在,则返回节点是不起作用的。对于我当前使用的默认值""
(空字符串(,是否有其他默认值或其他函数可以用于使其工作?
使用fn:exists()
函数可以测试abc
和qwert
元素是否存在。如果你想让它通过,如果这两个元素中的任何一个都不存在,你可以使用fn:not()
来否定abc
和qwert
存在的测试:
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"