反向XML子标记

时间:2011-01-25 14:52:38

标签: java xml-parsing

在Java中反转XML中的行/标记的最佳选择

e.g。

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

最终结果

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

使用这样的比较器:

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());        
                 }                                                            

         }       

3 个答案:

答案 0 :(得分:2)

这应该反转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 ) );
}

但是,如果您希望将特定订单实施为Comparator,则将节点放入使用比较器的LinkedList而不是TreeSet

答案 1 :(得分:2)

我遇到了转换RSS元素的问题,所以前面的评论很有启发,这里是代码:

{{1}}

答案 2 :(得分:1)

这是您可以使用的递归方法。它将所有子节点放在一个列表中,然后使用比较器对它们进行排序。我不认为您可以对属性进行排序,因为文档声明NamedNodeMaps不以任何顺序维护。

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());
    }
}