This discussion is archived
5 Replies Latest reply: Apr 28, 2011 7:43 AM by 655560 RSS

move node to another part of the document

756043 Newbie
Currently Being Moderated
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 Journeyer
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Journeyer
    Currently Being Moderated
    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 Journeyer
    Currently Being Moderated
    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 Journeyer
    Currently Being Moderated
    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

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points