XQuery не вставляет дочерний узел

Ниже представлена ​​структура XML. Это образец моей первоначальной структуры, а не точный.

<Docs>
  <Doc>
   <Para>
      <P n="1"><B>Constants : T</B>he value of pi is 3.14</P>
      <P n="2">pi is a geometric term.</P>
   </Para>
  </Doc>
  <Doc>
   <Para>
     <P n="1"><B>Constants : T</B>he value of g is 9.81 m/sqr of sec</P>
     <P n="2">g is a acceleration due to gravity.</P>
   </Para>
  </Doc>
  <Doc>
    <Para>
      <P n="1"><B>Constants : T</B>he value of c is 3.00 x 10 power 8 m/sec</P>
      <P n="2">c is a speed of light in vacuum.</P>
    </Para>
  </Doc>
</Docs>

Я создал файлы XML программно. Узел B содержит данные Constant : T, где в должном порядке должно быть только Constants :. Я написал XQuery для внесения необходимых изменений, но он работает не так, как ожидалось.

ниже XQuery - версия 1

for $x in doc('doc1')//Doc
where $x/Para/P[@n="1"]/B/text()="Constants : T"

return
let $p := $x/Para/P[@n="1"]
let $pText := concat("T", $p/text())
let $tag := <P n="1">{$pText}</P>

return
(
delete node $p,
insert node $tag as first into $x/Para,
insert node <B>Constants :</B> as first into $x/Para/P[@n="1"]  
)

Версия - 2 (поменьше, слаще, но не работает !!!)

let $b := <B> Constants :</B>
for $x in doc('doc1')//Doc/Para[P[@n="1"]/B/text()="Constants : T"]/P[@n="1"]

return
(
 replace value of node $x with concat("T", $x/text()),
 insert node $b/node() as first into $x
)

Ни один из запросов не вставляет <B>Constants : </B>. Кто-нибудь может мне в этом помочь?


person John    schedule 09.12.2013    source источник


Ответы (1)


Проблема, с которой вы столкнулись, связана с характером обновлений XQuery. Он использует список ожидающих обновлений и применяет все обновления в конце запроса. Порядок операции обновления четко определен и поэтому не зависит от порядка, который вы указываете в своем операторе обновления. Дополнительную информацию см. На странице https://docs.basex.org/wiki/Updates#Pending_Update_List.

Итак, в вашем случае insert применяется перед replace, поэтому вы фактически заменяете только что вставленный узел и, таким образом, перезаписываете это изменение.

Чтобы решить эту проблему, я бы просто заменил текстовые значения и заменил узел B. Следовательно, обе ваши операции независимы от других, и порядок их выполнения можно без проблем изменить.

let $b := <B> Constants :</B>
for $x in doc('doc1')//Doc/Para[P[@n="1"]/B/text()="Constants : T"]/P[@n="1"]

return
(
    replace value of node $x/text() with concat("T", $x/text()),
    replace node $x/B with $b
)
person dirkk    schedule 09.12.2013