开发者

Reverse XML Child tags

What is the best option to reverse the lines / tags in an XML in Java

e.g.

<?xml version="1.0"?>
<abc>
    <xyz1 test1="123" test2="345">
    </xyz1>
    <xyz2 test1="456">
    </xyz2>
</abc>
</xml>

End result

<?xml version="1.0"?>
    <abc>    
        <xyz2 test1="456">
        </xyz2>
        <xyz1 test2="345" test1="123">
        </xyz1>
    </abc>
</xml>

Using a comparator like this:

public int compare(Object arg0, Object arg1) {                                                                                                   
                 if (arg0 instanceof Element && arg1 instanceof Element) {    
                         return ((Element) arg0).getAttribute("id").compareTo(
                                         ((Element) arg1).getAttribute("id"));
                 } else {                                                     
                         return ((Node) arg0).getNodeName().compareTo(        
                                         ((Node) arg1).getNodeName());        
                 }          开发者_如何学Python                                                  

         }       


This should invert all the child nodes of element:

NodeList nl = element.getChildNodes();
LinkedList<Node> nodes = new LinkedList<Node>();
for( int i = 0; i < nl.getLength(); i++ ) {
  nodes.addFirst( nl.item( i ) );
}
for( Node node : nodes ) {
  element.appendChild( element.removeChild( node ) );
}

But if you want a specific order implemented as a Comparator, then instead of a LinkedList, put the nodes into a TreeSet that uses your comparator.


I have had a problem of reversing RSS elements, so inspiried by previous comment, here is the code:

    // RSS sorting of <items> by DESC
    NodeList nl = document.getElementsByTagName( "item" );
    LinkedList<Node> nodes = new LinkedList<Node>();
    for( int i = 0; i < nl.getLength(); i++ ) {
        nodes.addFirst( nl.item( i ) );
    }
    for( Node node : nodes ) {
        node.getParentNode().appendChild( node.getParentNode().removeChild( node ) );
    }


Here is a recursive method you can use. It puts all the child nodes in a list and then sorts them using your comparator. I don't think you can sort attributes, because the docs state that NamedNodeMaps are not maintained in any order.

public static void sortChildren(Node parent, Comparator<Node> comparator){
    NodeList children = parent.getChildNodes();
    if(children.getLength() == 0){
        return;
    }
    List<Node> nodes = new ArrayList<Node>();
    for(int i = 0 ; i < children.getLength() ; i++){
        Node n = children.item(i);
        sortChildren(n, comparator);
        nodes.add(n);
    }
    Collections.sort(nodes, Collections.reverseOrder(comparator));
    for(Node n : nodes){
        parent.appendChild(n);
    }
}

public static void main(String[] args) throws Exception {

    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("file.xml"));
    Element root = doc.getDocumentElement();

    //sort it recursively
    sortChildren(root, new DefaultNodeNameComparator());

    //print it out (for debugging)
    OutputFormat format = new OutputFormat(doc);
    format.setLineWidth(65);
    format.setIndenting(true);
    format.setIndent(2);
    Writer out = new StringWriter();
    XMLSerializer serializer = new XMLSerializer(out, format);
    serializer.serialize(doc);
    System.out.println(out.toString());
}

class DefaultNodeNameComparator implements Comparator<Node> {
    public int compare(Node arg0, Node arg1) {
        return arg0.getNodeName().compareTo(arg1.getNodeName());
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜