[jdom-interest] More on re-ordering elements: grandParent adopting child

Thomas Nichols thomas.nichols at iname.com
Thu May 17 14:42:16 PDT 2001


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.




More information about the jdom-interest mailing list