"xdmp:eval" 为可选外部参数传递“()”[空序列] 时抛出 "XDMP-ARG: -- vars is invalid" 异常

"xdmp:eval" throws "XDMP-ARG: -- vars is invalid" exception when "()" [empty sequence] is passed for an optional external parameter

下面是示例代码,其中 $p2 是一个 optional external parameter(即 ? modifier);当 empty sequence-() 传递给 $p2.

时,代码给出 XDMP-ARG: -- vars is invalid 异常

Marklogic 8 & 9

上试过了
let $query := 
"
declare variable $p1 as node()? external;
declare variable $p2 as node()? external;
(
if($p1) then xdmp:log('P1') else ()
,
if($p2) then xdmp:log('P2') else ()
)

"
let $p1 := <p></p>
let $p2 := ()
return 
xdmp:eval(
          $query,
          (xs:QName('p1'), $p1, xs:QName('p2'), $p2)
         )

我希望代码能够 运行 并打印日志。 我可以深入了解异常是如何发生的吗?

如果您将 vars 作为 key,val,key,val 的 Sequence 传递,它必须是偶数(2 的倍数)。您不能那样嵌入序列,因为嵌套序列在 XQuery 中会自动变平。使用 map:map:

传入你的变量
map:new((
  map:entry("p1", $p1),
  map:entry("p2", $p2),
))

HTH!

一个不太干净的替代方法是使用一个特殊的标记值来表示 'empty' 而不是文字空序列——正如 HTH 所说,在另一个序列中传递时不会保留(不仅是序列不是 'nest' 但空序列不是 'countable' 或 'identifiable' 值——不知道确切的术语)。

这应该证明:

  let $x := ( 1 , () , () , 2 )

$x 现在是一个长度为 2 而不是 4 的序列,空序列解析为空序列并且包含序列 'collapses'(删除插槽,不在其中放置一种 'null' 值)

因此,通常可以使用一种替代某种 'empty token' 的方法。 喜欢

  declare variable $empty :=  <empty/>  

(: 任何与非空用途兼容的单一值或节点类型都可以工作:)

现在

  let $x :=  (1,$empty,$empty,2)  (: sequence length 4 :)

因此您可以将 () 替换为 $empty 传递给 eval()。 被调用的代码也需要针对 $empty 进行测试

  if( $p1 != $empty ) then xdmp:log("P1 is" , $p1 )

此技术有时用于创建稀疏树结构,如二叉树、red/black 树等。

HTH的解决方案更好。 (这只是展示了一个替代方案,以帮助更好地理解核心问题)