Выполните xdmp: node-replace () для последовательности элементов и замените ее одним элементом - PullRequest
3 голосов
/ 05 марта 2020

Итак, у меня есть интересная проблема, предположим, у меня есть этот документ (пример. xml) внутри базы данных MarkLogi c:

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

Я хочу заменить все «активные» элементы регистрации с одним узлом, поэтому, по сути, мой конечный результат для этого должен быть:

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

Но это результат, который я get:

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

Код заменяет каждую активную регистрацию тем же узлом, который я указал для замены. Я хочу, чтобы он заменил оба узла одновременно только одним узлом. Как я могу это сделать и получить желаемый результат?

1 Ответ

3 голосов
/ 05 марта 2020

Попробуйте сделать 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>)
...