[jdom-interest] More on re-ordering elements: grandParent adopting child
Steven D. Keens
skeens at planetfred.com
Fri May 18 08:38:35 PDT 2001
Here's how I would write a replaceElement() method. The
problem with using this in a sort is that you everytime
you swap elements you have to re-find the old element
in the list which could be of order O(n). So you get a
sort of order O(n * n).
public void replaceElement( Element oldElement,
Element newElement )
{
// Omitting all the code to make this a robust method here's
// how I would write the
Element parent = oldElement.getParent();
List list = parent.getChildren();
int requestIdx = list.indexOf( oldElement );
// You have to detach() rather than remove().
oldElement.detach();
newElement.detach();
list.set( requestIdx, newElement );
}
-
Steven Keens mailto:skeens at planetfred.com
Planetfred Inc. http://www.planetfred.com
44 Byward Market, Suite 240, Ottawa, ON, K1N 7A2, Canada
The most exciting phrase in science, the one which heralds
new discoveries, is not "Eureka!", but "That's funny!"
-- Issac Asimov
>-----Original Message-----
>From: jdom-interest-admin at jdom.org
>[mailto:jdom-interest-admin at jdom.org]On Behalf Of Thomas Nichols
>Sent: Thursday, May 17, 2001 17:42
>To: JDOM Interest
>Subject: [jdom-interest] More on re-ordering elements: grandParent
>adopting child
>
>
>Thanks to all who responded to earlier query (off list) -- I had not
>understood that the PartialList returned by getContent is a "live" subList
>of content, this is very elegant.
>
>However, I still have a problem with the code below. This (I think!) takes
>a child element oldChild and replaces it with a newChild, keeping the same
>sequence within the parent. This quite simple task is proving difficult to
>implement in JDOM.
>
>The problem with the implementation below is
>thatPartialList.remove (Object
>o) resets the 'parent' link, so that children.addContent ((Element) o)
>throws NoSuchElementException.
>
> From PartialList.java:
>
> public boolean remove(Object o) {
> backingList.remove(o);
> if (o instanceof Element) {
> ((Element)o).setParent(null);
> }
> return super.remove(o);
>}
>
>The failing code:
>
> void replaceChild (Element parent, Element oldChild, Element
>newChild) {
> if (parent == null || oldChild == null)
> return;
> List children = parent.getChildren();
> int oldIndex = children.indexOf (oldChild);
> if (oldIndex != -1) {
> // Make sure newChild is an orphan, so that it can be adopted:
> if (newChild != null && newChild.getParent() != null)
> newChild.getParent().removeContent (newChild);
> // Now replace the child, using Element methods to
>ensure setParent()
>is called correctly:
> parent.removeContent (oldChild);
> parent.addContent (newChild); // Will be appended.
>newChild.parent == parent.
> // Now move newChild to the correct place in the list
>by directly
>manipulating the List. First refresh the list of children:
> children = parent.getChildren();
> children.remove (newChild); // Chop it from the
>end... ###
>Sets newChild.parent back to null!
> children.add (oldIndex, newChild); // ...and insert at
>the original
>position. ### throws NoSuchElementException.
> }
> }
>
>====
>
>One suggestion was to use
>Comparator comp = new YourComparator();
>List children = el.getMixedContent();
>Collections.sort( children, comp );
>
>This is a good idea for a general "sort" problem, but I'm not at all sure
>how to write a Comparator to do the above.
>
>The approach I'm currently pursuing is to empty the parent of all content,
>then put it back in again replacing oldChild with newChild.- please let me
>know if you have any better suggestions, performance is unimpressive.
>
>To clarify: I want newChild to take the place of oldChild, so that
>it comes
>in the same location in the tree. A simple solution is to add an "int
>index" parameter to the addContent call, and pass this through to
>List.add(...). Is this problem common enough to warrant it? (I've found
>several similar queries in the archives).
>
>Alternative solution: rather than adding a raft of addContent (int index
>(Blah blah) methods, just add a setAddContentIndex (int index),
>which would
>set the index for the next call of any flavour of addContent (resetting it
>afterwards).
>
>Of course if the *specific* problem I have here is seen as general enough,
>we could have an Element.replaceContent() family. Not sure this is wise,
>though.
>
>Thanks for all and any help,
>Regards,
>Thomas.
>
>_______________________________________________
>To control your jdom-interest membership:
>http://lists.denveronline.net/mailman/options/jdom-interest/youradd
r at yourhost.com
More information about the jdom-interest
mailing list