|
[XQuery Talk Mailing List Archive Home] [By Date] [By Thread] [By Subject] [By Author] [Recent Entries] [Reply To This Message] Help with multiple deletesNewman, John W newmanjw at upmc.eduFri Aug 28 17:10:41 PDT 2009
Thank you Michael.
One thing I should have mentioned in the original email, is that the leaf IDs can be shared across different branches. But branches are only used once across all trees. So if there is
<branch ID="2">
<branch ID="4">
<leaf ID="25" />
</branch>
<branch ID="8">
<leaf ID="25" />
</branch>
</branch>
That query would delete all three branches when the user only wants to delete branch 8. I was able to adjust it to also look at the parent branch ID.
delete node $x//branch[count(.//leaf[@ID != 25 or (@ID = 25 and (ancestor::branch[1])[@ID != 8])]) = 0]
After I spent a nice chunk of time testing this in stylus studio, I took the concept and ported it into our application. Only to discover that the implementation we are using, MXQuery 0.6.0, does not support ancestor! Argh.. =) So if anyone thinks it can possibly be rewritten without using ancestor (or any other axes I'm guessing), please share your thoughts. But I think we are going to end up using an XSLT for this operation.
-John
From: Michael Kay [mailto:http://x-query.com/mailman/listinfo/talk]
Sent: Friday, August 28, 2009 1:52 PM
To: Newman, John W; http://x-query.com/mailman/listinfo/talk
Subject: RE: Help with multiple deletes
>Or better yet, can anyone think of a one pass solution to this problem?
Change the second delete to
delete node $x//branch[count(.//leaf[@ID != 25]) = 0]
Regards,
Michael Kay
http://www.saxonica.com/
http://twitter.com/michaelhkay
________________________________
From: http://x-query.com/mailman/listinfo/talk [mailto:http://x-query.com/mailman/listinfo/talk] On Behalf Of Newman, John W
Sent: 28 August 2009 17:31
To: http://x-query.com/mailman/listinfo/talk
Subject: Help with multiple deletes
Hello,
I have a tree structure and I am trying to use XQuery to delete nodes from it. Here's a simple example of what I have and what needs to happen:
<tree ID="1">
<branch ID="1">
<branch ID="4"
<leaf ID="6" />
</branch>
</branch>
<branch ID="2">
<branch ID="13">
<branch ID="34">
<leaf ID="15" />
<leaf ID="16" />
</branch>
<branch ID="65">
<branch ID="15">
<leaf ID="25" />
</branch>
</branch>
</branch>
</branch>
</tree>
The user is allowed to delete leaf nodes. Say the user clicks delete on leaf 25 there, I'm building an XPath expression down to it, like so:
//tree[@ID = 1] /branch[@ID = 2] /branch[@ID = 13] /branch[@ID = 65] /branch[@ID = 15] /leaf[@ID = 25]
The problem is, after deleting the leaf node, I am left with a 'dead' branch. So branch 15 should also be deleted, and so on up the tree, in this case branch 65 also. Branches 2 & 13 are left in place since count(.//leaf) > 0
I think there are probably several ways to do this with XQuery. My current approach should work, in theory, although I am too new to XQuery to figure out how to write it correctly. :) I think there is probably a clean, 1 line solution somewhere. Anyway, this is what I am currently trying:
Step 1, delete the leaf itself
copy $x := doc("tree.xml")
modify (
delete node $x//tree[@ID = 1] /branch[@ID = 2] /branch[@ID = 13] /branch[@ID = 65] /branch[@ID = 15] /leaf[@ID = 25]
)
return $x
This correctly gives back the tree without that leaf, but it leaves dead branches:
<tree ID="1">
<branch ID="1">
<branch ID="4"
<leaf ID="6" />
</branch>
</branch>
<branch ID="2">
<branch ID="13">
<branch ID="34">
<leaf ID="15" />
<leaf ID="16" />
</branch>
<branch ID="65">
<branch ID="15">
</branch>
</branch>
</branch>
</branch>
</tree>
So, step 2, delete any branches that don't have leaves underneath, and then likewise any trees that don't have branches:
copy $x := doc("tree.xml")
modify (
delete node $x//tree[@ID = 1] /branch[@ID = 2] /branch[@ID = 13] /branch[@ID = 65] /branch[@ID = 15] /leaf[@ID = 25]
,
delete node $x//tree//branch[count(.//leaf) = 0]
,
delete node $x//tree[count(.//branch) = 0]
)
return $x
However the 2nd delete isn't exactly working, the dead branches are still there. I think since it is operating on $x which is the original document that has the leaf in place. If I save the output of each delete into a separate doc, and run each step one at a time, they work fine. So how I do write this query to operate on the same xml structure throughout? Or better yet, can anyone think of a one pass solution to this problem?
Thanks,
John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://x-query.com/pipermail/talk/attachments/20090828/09df7e78/attachment-0001.htm
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|






