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