XQuery 将节点附加到现有节点集

XQuery to append node to existing node set

我不熟悉 XQuery 和 XSLT。 WebLogic 正在使用 XQuery 1.0。

我有一个 WebLogic 组合和一个节点集合,只想将一个节点添加到 XQuery 分配中的现有节点集。我目前的解决方案似乎过于重量级。我将处理数以万计的记录,在我看来应该有一种非常简单的方法可以将一个节点插入另一个节点下并 return 它。

declare function local:func($svdPpl as element() (:: element(*,  sv:svdPpl) ::), 
                            $svdPsn as element() (:: element(*, sv:svdPsn) ::)) 
                            as element() (:: element(*,  sv:svdPpl) ::) {
   <sv:svdPpl>
   {for $psn in $svdPpl return $psn} {$svdPsn}
   </sv:svdPpl>
};

如果我对 XQuery 的理解正确,那意味着数百万个循环只是为了向现有节点集添加记录。我已尝试使用插入节点 $svdPsn 到 $svdPpl 语法中,但这会导致 WebLogic 编辑器中出现验证错误。

感谢任何帮助。

XQuery 是一种函数式语言,变量是不可变的。一旦使用标准 XQuery 进行赋值,就不可能更改变量的值。

XQuery 有一个名为 XQuery Update Facility 的允许更新的扩展,但并非所有处理器都实现它。我不熟悉 WebLogic,但看起来有些版本支持它。那将是直接路线。

如果做不到这一点,一种常见的模式是编写一个通用的递归 typeswitch 函数来遍历树并在生成输入的修改副本时应用转换逻辑。这就是 XSLT 中隐式工作的方式。从您的问题中不清楚具体将如何实施,但仅作为示例:

declare function local:add-after(
  $context as item(),
  $target-name as xs:QName,
  $payload as item()*
) as item()*
{
  typeswitch ($context)
  case element() return (
    element { node-name($context) } {
      $context/@*, 
      for $n in $context/node()
      return local:add-after($n, $target-name, $payload)
    },
    if (node-name($context) = $target-name)
    then $payload
    else ())
  default return $context  
};

给定一个 XML 节点 $xml,其值为:

<x>
  <y>
    <z></z>
  </y>
</x>

您可以使用上述函数 local:add-after($xml, xs:QName('y'), <payload/>)<y> 元素之后添加有效载荷:

<x>
  <y>
    <z></z>
  </y>
  <payload></payload>
</x>