5 Replies Latest reply: Apr 28, 2011 9:43 AM by 655560 RSS

    move node to another part of the document

    756043
      Hi,

      I have a problem moving nodes from one part of the document to another.
      This is the xquery I execute after checking that all the nodes requests exists.
      let $area :=doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea//area[@idArea="5"]
      let $areaPadre :=doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea//area[@idArea="9"]
      return ( insert node $area as last into $areaPadre, delete node $area) 
      With this xquery I want to delete node <area @idArea="5"/> from its original position and insert it as a child of <area @idArea="9"/>

      It sometimes do it right, but sometimes it duplicates the node, but it isn't remove from its original position.

      I used Berkeley DB XML in Solaris. I can give more information if it's necessary.

      Thank you
        • 1. Re: move node to another part of the document
          637288
          Hi,

          1) did you test your query with other XQuery processors?
          2) What is the structure of your document?
          3) Maybe you meant: insert nodes $area after $areaPadre ?

          Vyacheslav
          • 2. Re: move node to another part of the document
            756043
            I don't understand your first question, sorry.

            The structure of the document is like this:
            <client>
                 <users>
                      <user idUser="">
                           <nameUser/>
                           ...
                      </user>
                      <user idUser="">
                           <nameUser/>
                      </user>
                      ...
                 </users>
                 <rootArea>
                      <area idArea="1">
                           <nameArea/>
                           <area idArea="1.1">
                                <nameArea/>
                           </area>
                           <area idArea="1.2">
                                <nameArea/>
                                <area idArea="1.2.1">
                                     <nameArea/>                    
                                </area>
                           </area>
                      </area>
                      <area idArea="2">
                           <nameArea/>
                      </area>
                      <area idArea="3">
                           <nameArea/>
                           <area idArea="3.1">
                                <nameArea/>
                                <area idArea="3.1.1">
                                     <nameArea/>
                                </area>
                           </area>
                      </area>
                      ...
                 </rootArea>
            <client>
            For example, if I execute:
            let $area :=doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea//area[@idArea="1.2"]
            let $areaPadre :=doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea//area[@idArea="3"]
            return ( insert node $area as last into $areaPadre, delete node $area)
            I want to get this final state in the document
            <client>
                 <users>
                      <user idUser="">
                           <nameUser/>
                           ...
                      </user>
                      <user idUser="">
                           <nameUser/>
                      </user>
                      ...
                 </users>
                 <rootArea>
                      <area idArea="1">
                           <nameArea/>
                           <area idArea="1.1">
                                <nameArea/>
                           </area>
                      </area>
                      <area idArea="2">
                           <nameArea/>
                      </area>
                      <area idArea="3">
                           <nameArea/>
                           <area idArea="3.1">
                                <nameArea/>
                                <area idArea="3.1.1">
                                     <nameArea/>
                                </area>
                           </area>
                           <area idArea="1.2">
                                <nameArea/>
                                <area idArea="1.2.1">
                                     <nameArea/>                    
                                </area>
                           </area>
                      </area>
                      ...
                 </rootArea>
            <client>
            Thanks
            • 3. Re: move node to another part of the document
              655560
              Hi,

              1) It should be
              /area[@idArea="1.2"]
              not *"//area[@idArea="1.2"]*". Since "//" always get all "<area>" in rootArea. So for some "<area>", which has been inserted into "<area idArea="3">", would be operated (deleted and insert) again. Some conflict occurs here.

              2) Sometimes there are more then one 'area[@idArea="1.2"]'. So please try to use "for" instead of "let". e.g.:
              for $area in doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea/area[@idArea="1.2"]
              Best regards,
              Rucong

              Edited by: Rucong Zhao on Apr 28, 2011 5:52 PM
              • 4. Re: move node to another part of the document
                637288
                It should be
                /area[@idArea="1.2"]
                not "//area[@idArea="1.2"]". Since "//" always get all "<area>" in rootArea.
                a query with single slash ("/area[@idArea="1.2"]") will return nothing since the rootArea element has no children "area" with attribute idArea equal to "1.2". I don't see any problems of using // since the attribute idArea seems to be unique across the document.

                By different XQuery processors I mean other XML databases (e.g. eXist or xDB), or XQuery processors like Saxon or XQilla.

                I'm suspecting that it could be a bug, especially taking into account that the behavior is not deterministic.
                As a workaround (or at least something to test with) you could move a node by two XQueries but in a single transaction.

                Vyacheslav
                • 5. Re: move node to another part of the document
                  655560
                  Hi Vyacheslav, and the Requester
                  >
                  a query with single slash ("/area[@idArea="1.2"]") will return nothing since the rootArea element has no children "area" with attribute idArea equal to "1.2". I don't see any problems of using // since the attribute idArea seems to be unique across the document.
                  Vyacheslav: Thanks for your comments. Since above posts only show parts of the doc, I'm not sure if the idArea is unique. If it is always unique, using "//" is OK.

                  Above post mentioned: "It sometimes do it right, but sometimes it (doesn't)". I don't know what "sometimes" means. If 'area[@idArea="1.2"]' is unique and there is no new 'area[@idArea="1.2"]' would inserted, why the query need to be called many times?

                  I create and new dbxml database with dbxml-2.5.16, and insert above xml content, then query with the given XQuery:
                  openc doPlanning.dbxml
                  query '
                  let $area := doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea//area[@idArea="1.2"]
                  let $areaPadre := doc("dbxml:/doPlanning.dbxml/doPlanning.xml")/client/rootArea//area[@idArea="3"]
                  return ( insert node $area as last into $areaPadre, delete node $area)'
                  getdoc
                  print
                  quit
                  And the query result is as expected:
                  <client>
                          <users>
                                  <user idUser="">
                                          <nameUser/>
                                  </user>
                                  <user idUser="">
                                          <nameUser/>
                                  </user>
                          </users>
                          <rootArea>
                                  <area idArea="1">
                                          <nameArea/>
                                          <area idArea="1.1">
                                                  <nameArea/>
                                          </area>
                  
                                  </area>
                                  <area idArea="2">
                                          <nameArea/>
                                  </area>
                                  <area idArea="3">
                                          <nameArea/>
                                          <area idArea="3.1">
                                                  <nameArea/>
                                                  <area idArea="3.1.1">
                                                          <nameArea/>
                                                  </area>
                                          </area>
                                  <area idArea="1.2">
                                                  <nameArea/>
                                                  <area idArea="1.2.1">
                                                          <nameArea/>
                                                  </area>
                                          </area></area>
                          </rootArea>
                  </client>
                  I executed above query for 50+ times and there is no failure. So more information about the reproducing would be helpful.

                  Best regards,
                  Rucong