[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().

        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
>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,
>Thanks for all and any help,
>To control your jdom-interest membership:
r at yourhost.com

More information about the jdom-interest mailing list