当为可选的外部参数传递“()” [空序列]时,“ xdmp:eval”抛出“ XDMP-ARG:-vars无效”异常

时间:2019-09-05 12:46:29

标签: marklogic marklogic-8 marklogic-9

下面是示例代码,其中$p2optional external parameter(即? modifier);当对XDMP-ARG: -- vars is invalid传递empty sequence-()时,代码给出$p2异常。

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)
         )

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

2 个答案:

答案 0 :(得分:5)

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

传入您的var
map:new((
  map:entry("p1", $p1),
  map:entry("p2", $p2),
))

HTH!

答案 1 :(得分:1)

一种不太干净的替代方法是使用特殊的标记值来表示“空”,而不是原义的空序列-正如HTH所说,当传入另一个序列时,该序列不会保留(不仅序列不是“嵌套”)但是空序列不是精确的“可计数”或“可识别”值-不知道精确的术语。

这应该表明:

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

$ x现在是一个长度为2而不是4的序列,空序列解析为空,并且包含的​​序列“塌陷”(删除插槽,而不在其中放入一种“空”值)

因此,通常可以使用一种方法来代替某种“空令牌”。 像

  declare variable $empty :=  <empty/>  

(:任何与非空用途兼容的单个值或节点类型都将起作用:)

现在

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

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

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

有时会使用这种技术来创建稀疏树结构,例如二叉树,红/黑树等。

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