XQuery not inserting child node

Below is the XML structure. Its a specimen of my original structure, not the exact.

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

I have generated XML files programmatically. The B node has data Constant : T, where as it should be only Constants :. I have written an XQuery to do the necessary changes, but its not working as expected.

below is the XQuery - Version 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"]  
)

Version - 2 (Smaller, sweeter but not working !!!)

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
)

Neither query is inserting <B>Constants : </B>. Can anybody help me on this?

Answers


The problem you are facing has to do with he nature of XQuery Updates. It uses a pending update list and applies all updates at the end of the query. The order of the update operation is well defined and is therefore independent from the order you give in your update statement. See some more information at https://docs.basex.org/wiki/Updates#Pending_Update_List.

So in your case, insert is applied before replace, so you are actually replacing your just already inserted node and thus overwrite this change.

To resolve this, I would just replace the text values and replace the B node. Therefore, both of your operations are independent from another and their order of execution can be changed without a problem.

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
)

Need Your Help

draw rounded edge arc in android with embossed effect

android android-canvas

I am trying to develop a custom component i.e. arc slider, I am done with the arc and the thumb but not able to figure out how can I draw the rounded edge arc and also the embossed effect in it. at...

CacheServiceEmulator.exe >3GB RAM usage?

caching azure azure-caching

I am developing an application for windows azure using the latest SDK.