<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2655.35">
<TITLE>RE: [jdom-interest] Moving elements </TITLE>
</HEAD>
<BODY>
<P><FONT SIZE=2>I have used the following code in the past .....</FONT>
</P>
<P><FONT SIZE=2>Basically, because DTD's are cumbersome if the child elements are not in a particular order, I wrote the following code to re-order the child elements to conform to the expected order of the DTD. Does both of your criteria, detatch, re-order. It is memory-hungry in the sense that it is recursive, and the memory is kept during recursion. The "plus" side for me is that it reorders just the elements, and any "mixed" content is left in the same order. This is obviously application specific, so YMMV.</FONT></P>
<P><FONT SIZE=2>Rolf</FONT>
</P>
<P><FONT SIZE=2> private static void reorderElements (Element element, Comparator comp) {</FONT>
<BR><FONT SIZE=2> if (element.getChildren().isEmpty()) return;</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> // Try to do the whole thing without a clone... Use detach only.</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> LinkedList list = new LinkedList();</FONT>
<BR><FONT SIZE=2> LinkedList kids = new LinkedList();</FONT>
<BR><FONT SIZE=2> List content = element.getContent();</FONT>
<BR><FONT SIZE=2> </FONT>
<BR><FONT SIZE=2> while (!content.isEmpty()) {</FONT>
<BR><FONT SIZE=2> // This removes and detaches element.</FONT>
<BR><FONT SIZE=2> Object o = content.remove(0);</FONT>
<BR><FONT SIZE=2> // add the detached object to our list, in same order.</FONT>
<BR><FONT SIZE=2> list.add(o);</FONT>
<BR><FONT SIZE=2> // add to our list of kids, if element</FONT>
<BR><FONT SIZE=2> if (o instanceof Element) kids.add(o);</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> Collections.sort(kids, comp);</FONT>
<BR><FONT SIZE=2> for (int i = 0; i < list.size(); i++) {</FONT>
<BR><FONT SIZE=2> if (list.get(i) instanceof Element) {</FONT>
<BR><FONT SIZE=2> Element rep = (Element)kids.remove(0);</FONT>
<BR><FONT SIZE=2> reorderElements(rep, comp);</FONT>
<BR><FONT SIZE=2> list.set(i,rep);</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> }</FONT>
<BR><FONT SIZE=2> element.setContent(list);</FONT>
<BR><FONT SIZE=2> }</FONT>
</P>
<P><FONT SIZE=2>-----Original Message-----</FONT>
<BR><FONT SIZE=2>From: Bradley S. Huffman [<A HREF="mailto:hip@a.cs.okstate.edu">mailto:hip@a.cs.okstate.edu</A>]</FONT>
<BR><FONT SIZE=2>Sent: Thursday, May 01, 2003 12:00 AM</FONT>
<BR><FONT SIZE=2>To: Jason Hunter</FONT>
<BR><FONT SIZE=2>Cc: jdom-interest@jdom.org</FONT>
<BR><FONT SIZE=2>Subject: Re: [jdom-interest] Moving elements </FONT>
</P>
<BR>
<P><FONT SIZE=2>Jason Hunter writes:</FONT>
</P>
<P><FONT SIZE=2>> 2) We could have a new method like this on Element and Document:</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> List element.getContentDetached()</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> It would return a list of the detached content. Then you could do this:</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> heading.setContent(anchorList.getContentDetached());</FONT>
</P>
<P><FONT SIZE=2>Definitely +1, but I'd just go ahead and name it removeContent().</FONT>
</P>
<P><FONT SIZE=2>> 3) We could change the add semantics. David Flanagan suggested this,</FONT>
<BR><FONT SIZE=2>> and it's how DOM does things. If you add an element somewhere and the</FONT>
<BR><FONT SIZE=2>> element already has a parent, the new parent just trumps it. Compare</FONT>
<BR><FONT SIZE=2>> that to right now we throw an IllegalAddException. If we changed</FONT>
<BR><FONT SIZE=2>> behaviors, it would make nice code:</FONT>
</P>
<P><FONT SIZE=2>Better documentation is also a solution :) But if the remove/add sequence is</FONT>
<BR><FONT SIZE=2>not convenient enough, I'd prefer a moveContent(...) on Element instead of</FONT>
<BR><FONT SIZE=2>changing the add semantics.</FONT>
</P>
<P><FONT SIZE=2> heading.moveContent(textNode); // Move textNode to end of heading's</FONT>
<BR><FONT SIZE=2> // content list.</FONT>
</P>
<P><FONT SIZE=2>> heading.setContent(anchorList.getContent());</FONT>
</P>
<P><FONT SIZE=2>Hmmm, does that a) detach the content from anchorList or b) make</FONT>
<BR><FONT SIZE=2>a copy of anchorList before setting heading's content. It's not clear just</FONT>
<BR><FONT SIZE=2>by looking at it. I like</FONT>
</P>
<P><FONT SIZE=2> heading.setContent(anchorList.removeContent());</FONT>
</P>
<P><FONT SIZE=2>> Sorting works naturally also. The big issue is whether you expect this</FONT>
<BR><FONT SIZE=2>> sort of auto-detachment. I guess I wouldn't, but maybe I've used JDOM</FONT>
<BR><FONT SIZE=2>> too long. :-)</FONT>
</P>
<P><FONT SIZE=2>I wouldn't either, and besides</FONT>
</P>
<P><FONT SIZE=2> List list = anchorList.removeContent();</FONT>
<BR><FONT SIZE=2> // do the sort</FONT>
<BR><FONT SIZE=2> heading.setContent(list);</FONT>
</P>
<P><FONT SIZE=2>is very clear about what is actual being done.</FONT>
</P>
<P><FONT SIZE=2>Brad</FONT>
<BR><FONT SIZE=2>_______________________________________________</FONT>
<BR><FONT SIZE=2>To control your jdom-interest membership:</FONT>
<BR><FONT SIZE=2><A HREF="http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@yourhost.com" TARGET="_blank">http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@yourhost.com</A></FONT>
</P>
</BODY>
</HTML>