对一系列元素执行 xdmp:node-replace() 并将其替换为一个元素

Doing a xdmp:node-replace() for a sequence of elements and replace that with one element

所以我有一个有趣的问题,假设我在 MarkLogic 数据库中有这个文档 (example.xml):

<Enrolls>
  <Enroll>
    <Status> Active </Status>
    <boom> boom2 </boom>
  </Enroll>
    <Enroll>
    <Status> Active </Status>
    <boom> boom </boom>
  </Enroll>
  <Enroll>
    <Status> Inactive </Status>
    <boom> boom </boom>
  </Enroll>
</Enrolls>

我想用一个节点替换所有 "Active" Enroll 元素,所以基本上我的最终结果应该是:

<Enrolls>
  <boom> boom for the actives </boom>
  <Enroll>
    <Status> Inactive </Status>
    <boom> boom </boom>
  </Enroll>
</Enrolls>

为了完成这个,这是我写的代码:

xdmp:node-replace((doc("example.xml")/Enrolls/Enroll[Status eq " Active "]), <boom> boom for the actives </boom>)

但这是我得到的结果:

<Enrolls>
  <boom> boom for the actives </boom>
  <boom> boom for the actives </boom>
  <Enroll>
    <Status> Inactive </Status>
    <boom> boom </boom>
  </Enroll>
</Enrolls>

代码将每个活动注册替换为我指定要替换的同一节点。我希望它只用一个节点同时替换两个节点。我怎样才能做到这一点并获得我想要的结果?

考虑对活跃的进行 xdmp:node-delete,对父级进行单独的 xdmp:node-insert-child

for $active in doc("example.xml")/Enrolls/Enroll[Status eq " Active "]
return 
  if ($active/following-sibling::Enroll[Status eq " Active "])
  then xdmp:node-delete($active)
  else xdmp:node-replace($active, <boom> boom for the actives </boom>)

或者第一个 xdmp:node-replace,其他 xdmp:node-delete。您应该能够在一个请求中完成所有这些,因此它只是一次提交。

let $enrolls := doc("example.xml")/Enrolls
return ( 
  $enrolls/Enroll[Status eq " Active "]/xdmp:node-delete(.),
  xdmp:node-insert-child($enrolls, <boom> boom for the actives </boom>)
)

您也可以重建父节点,然后将其全部替换。这可能更容易推理,并且在性能上可能相似。

let $enrolls := doc("example.xml")/Enrolls
return 
  xdmp:node-replace($enrolls, 
    <Enrolls>
      <boom> boom for the actives </boom>
      {$enrolls/* except $enrolls/Enroll[Status eq " Active "]}
    </Enrolls>)