I'd do it with dom4j. A dom4j Element
provides a live List view of its sub-elements, which you can sort. And with a Visitor
you can modify an entire document:
Document document = DocumentHelper.parseText(someXml);
final Comparator<Element> comparator = new Comparator<Element>() {
public int compare(Element o1, Element o2) {
return o1.getName().compareTo(o2.getName());
}
};
Visitor visitor = new VisitorSupport() {
@Override
public void visit(Element node) {
@SuppressWarnings("unchecked") // dom4j doesn't know generics yet
List<Element> elements = node.elements();
Collections.sort(elements, comparator);
super.visit(node);
}
};
document.accept(visitor);
// now write the document back to a file
It doesn't get much easier than this.
Update: After trying to use my own solution much later, I realized that it doesn't work that way. The list returned by Element.elements()
doesn't like Collections.sort()
, so you will have to use the List returned by Element.content()
. Unfortunately this means that your comparator will have to deal with Node
, rather than Element
, which will get very messy if you have mixed content.