I have been trying to reorder xml elements based on their child getTextContent value, but everything that I tried only worked for siblings nodes
Basically, I have this XML:
<order>
<item>
<item-id>d54829d52c3f2810VgnVCM1000001af614ac</item-id>
<item-order>3</item-order>
</item>
<item>
<item-id>b54829d52c3f2810VgnVCM1000001af614ac</item-id>
<item-order>1</item-order>
</item>
<item>
<item-id>f54829d52c3f2810VgnVCM1000001af614ac</item-id>
<item-order>2</item-order>
</item>
</order>
And I would like to achive this result, ordering using "item-order":
<order>
<item>
<item-id>b54829d52c3f2810VgnVCM1000001af614ac</item-id>
<item-order>1</item-order>
</item>
<item>
<item-id>f54829d52c3f2810VgnVCM1000001af614ac</item-id>
<item-order>2</item-order>
</item>
<item>
<item-id>d54829d52c3f2810VgnVCM1000001af614ac</item-id>
<item-order>3</item-order>
</item>
</order>
I have been trying some implementations like this example based on the website below that I found on internet, but it does not work.
http://programmatica.blogspot.com/2006/12/sorting-xml-in-java.html How to sort XML elements by value of attributes in Java?
static class MyComparator4 implements Comparator {
public int compare(Object arg0, Object arg1) {
if (arg0 instanceof Element && arg1 instanceof Element) {
Element e0 = (Element) arg0;
Element e1 = (Element) arg0;
e0.getChildNodes().item(e0.getChildNodes().getLength()-1).getTextContent().compareTo(e1.getChildNodes().item(e1.getChildNodes().getLength()-1).getTextContent());
} else {
return ((Node) arg0).getNodeName().compareTo(
((Node) arg1).getNodeName());
}
}
}
Any help is appreciate. Thank you in advance
CodePudding user response:
You can use the class (public class NodeTools) from your 2nd example (link) with the Integer class which is comparable.
Node[] ret = NodeTools.sortNodes(doc.getElementsByTagName("item"), "item-order", true, Integer.class);
CodePudding user response:
Based on what @mazi suggested, I was able to achieve the ordering changing a little bit the method NodeTools.sortNodes.
Basically, I have changed this part:
bda = (Comparable)bc.newInstance(((Element)a).getAttribute(attributeName));
bdb = (Comparable)bc.newInstance(((Element)b).getAttribute(attributeName));
To this:
bda = (Comparable)bc.newInstance(((Element)a).getElementsByTagName(attributeName).item(0).getTextContent());
bdb = (Comparable)bc.newInstance(((Element)b).getElementsByTagName(attributeName).item(0).getTextContent());
Here goes the whole code:
import java.lang.reflect.Constructor;
import java.util.*;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import org.w3c.dom.Document;
public class NodeTools {
public static Node[] sortNodes(NodeList nl, String attributeName, boolean asc, Class B)
{
class NodeComparator implements Comparator
{
@Override
public int compare(T a, T b)
{
int ret;
Comparable bda = null, bdb = null;
try{
Constructor bc = B.getDeclaredConstructor(String.class);
bda = (Comparable)bc.newInstance(((Element)a).getElementsByTagName(attributeName).item(0).getTextContent());
bdb = (Comparable)bc.newInstance(((Element)b).getElementsByTagName(attributeName).item(0).getTextContent());
//bda = (Comparable)bc.newInstance(((Element)a).getAttribute(attributeName));
//bdb = (Comparable)bc.newInstance(((Element)b).getAttribute(attributeName));
}
catch(Exception e)
{
return 0; // yes, ugly, i know :)
}
ret = bda.compareTo(bdb);
return asc ? ret : -ret;
}
}
List x = new ArrayList();
for(int i = 0; i ());
return ret;
}
public static void main(String... args)
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
String s = "\n"
" \n"
" d54829d52c3f2810VgnVCM1000001af614ac\n"
" 3\n"
" \n"
" \n"
" b54829d52c3f2810VgnVCM1000001af614ac\n"
" 1\n"
" \n"
" \n"
" f54829d52c3f2810VgnVCM1000001af614ac\n"
" 2\n"
" \n"
"";
Document doc = null;
try
{
builder = factory.newDocumentBuilder();
doc = builder.parse(new InputSource(new StringReader(s)));
}
catch(Exception e) { System.out.println("Alarm " e); return; }
Node[] ret = NodeTools.sortNodes(doc.getElementsByTagName("item"), "item-order", true, Integer.class);
for(Node n: ret)
{
System.out.println(((Element)n).getTextContent());
}
}
}
Here is the output:
b54829d52c3f2810VgnVCM1000001af614ac
1
f54829d52c3f2810VgnVCM1000001af614ac
2
d54829d52c3f2810VgnVCM1000001af614ac
3