Sort XML in Java

I have an XML similar to the one below that needs to be sorted using a date field.

<root> <Node1> <date></date> </Node1> <Node1> <date></date> </Node1> <Node1> <date></date> </Node1> <Node1> <date></date> </Node1> <Node2> <date></date> </Node2> <Node2> <date></date> </Node2> <Node2> <date></date> </Node2> <Node2> <date></date> </Node2> </root> 

I would like to sort the XML based on the date (say, in ascending order), regardless of whether the date is under Node1 or Node2. In fact, in Java code, I have two separate lists, one with Node1 objects, and the other with Node2 objects. I can sort the list in any order separately inside Java. But I need to sort the dates no matter which nodes appear in the XML. What is the best way to sort in Java?

I actually use Castor to marshal Java objects in XML. If you know that you can do it with Castor, it will be great!

+7
java xml castor
source share
4 answers

I would use XSLT, it has problems with sort dates that you will need to work in the simplest way, if you can manage it to have a sorted date format like yyyymmdd

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="root"> <xsl:copy> <xsl:apply-templates> <xsl:sort data-type="number" select="date"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> 
+2
source share
+1
source share

If you want the sort result to be the only list sorted by date, you must put all the nodes in one list in the array. If two types (node1 and node2) extend a common base class, you can use Java Generics for your list.

 List<Node> nodes = new ArrayList<Node>(); nodes.add(node1); nodes.add(node2); Node[] nodeArrayToSort = nodes.toArray(); 

If the two types of node are not inherited from the general class, you can simply use the List of objects.

Now you have to write your own comparator. here is an example of what you could use if node types have a common superclass that contains a Date field.

 public class NodeComparator implements Comparator<Node> { @Override public int compare(Node node1, Node node2) { return node1.getDate().compare(node2.getDate()); } } 

Now that you have your custom comparator and your array with all your nodes, this is one line of Java code to sort the list.

 Arrays.sort(nodeArrayToSort, new NodeComparator()); 

The javadoc for the above method can be found here if you want more information about its behavior.

Using the above method, it's easy to see how you could write any comparison function to change the behavior of your type. You can also write as many custom Comparator classes as you want so you can switch them at runtime. Hope this helps! :)

0
source share

I used XSLT and XALAN.

XSL is as follows. Date is in the format mm / dd / yyyy

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="root"> <xsl:copy> <xsl:apply-templates> <xsl:sort data-type="number" select="substring(date,7,4)"/> <!-- year sort --> <xsl:sort data-type="number" select="substring(date,1,2)"/> <!-- day sort --> <xsl:sort data-type="number" select="substring(date,4,2)"/> <!-- month sort --> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> 

and the java code is

 import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; /** * Use the TraX interface to perform a transformation in the simplest manner possible * (3 statements). */ public class SimpleTransform { public static void main(String[] args) throws TransformerException, TransformerConfigurationException, FileNotFoundException, IOException { // Use the static TransformerFactory.newInstance() method to instantiate // a TransformerFactory. The javax.xml.transform.TransformerFactory // system property setting determines the actual class to instantiate -- // org.apache.xalan.transformer.TransformerImpl. TransformerFactory tFactory = TransformerFactory.newInstance(); // Use the TransformerFactory to instantiate a Transformer that will work with // the stylesheet you specify. This method call also processes the stylesheet // into a compiled Templates object. Transformer transformer = tFactory.newTransformer(new StreamSource("sort.xsl")); // Use the Transformer to apply the associated Templates object to an XML document // (foo.xml) and write the output to a file (foo.out). transformer.transform(new StreamSource("root.xml"), new StreamResult(new FileOutputStream("out.xml"))); System.out.println("************* The result is in birds.out *************"); } } 
0
source share

All Articles