2010-05-26 21 views
6

Hola tengo un XML similar al de abajo, que debe ser ordenado usando el campo de fecha.Ordenando un XML en Java

<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> 

quisiera ordenar el XML basado en la fecha (por ejemplo para ASC), con independencia de si la fecha está bajo el nodo 1 o Nodo2. En realidad, en el código de Java, tengo dos listas separadas, una con objetos Node1 y otra con Nodo2. Puedo ordenar la lista en cualquier orden speradamente dentro de java. Pero necesito tener las fechas ordenadas independientemente de los nodos que está apareciendo en el XML. ¿Cuál es el mejor enfoque para ordenar de esta manera en Java?

Actaully Estoy usando Castor para ordenar los objetos de Java en XML. Si sabes que esto se puede hacer con Castor, ¡eso será genial!

+0

Gracias! Justin ... –

+0

XML se "pretende" ser un conjunto, por lo que ordenar los datos en orden ascendente no "pretende" ser útil ... – blissapp

+4

@blissapp - El orden es fundamental para XML, el modelo abstracto es una secuencia . la base de xpath 2.0/xquery. ¿Tal vez estás pensando en datos relacionales? – mdma

Respuesta

2

que haría uso de XSLT, tiene hubieron problemas con la clasificación de las fechas que usted necesita para trabajar redonda, forma más sencilla si se puede controlar es tener formato de fecha clasificable como aaaammdd

<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> 
+0

Gracias .... ........ –

+0

tengo el mismo caso, pero el formato de fecha es diferente, como 2015-12-27T16: 44: 07, entonces cómo se puede hacer en ese caso –

0

Si lo haría como el resultado del género es una lista única, ordenada por fecha, entonces tiene que poner todos los nodos en una sola lista de matriz. Si los dos tipos (node1 & node2) amplían una clase base común, puede usar los genéricos de Java para su lista.

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

Si los dos tipos de nodo no heredan de una clase común, simplemente puede usar una Lista de objetos.

Ahora tendrá que escribir su propio comparador. Aquí hay un ejemplo de uno que podría usar si los tipos de nodo tienen una superclase común que contiene el campo Fecha.

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

Ahora que tiene su comparador de aduana y de su matriz con todos sus nodos, es una sola línea de código Java para ordenar la lista.

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

el Javadoc para el método anterior se puede encontrar here si desea alguna información adicional acerca de su comportamiento.

Usando el método anterior, es fácil ver cómo se puede escribir cualquier tipo de función de comparación para cambiar el comportamiento de su género. También puede escribir tantas clases comparativas personalizadas como desee para poder cambiarlas en tiempo de ejecución. ¡Espero que esto ayude! :)

0

Utilicé XSLT y XALAN.

El XSL es como el más abajo ..Fecha tiene el formato dd/mm/aaaa

<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> 

y el código java es

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

Genial, es bueno ver cómo Hágalo en Java. Su respuesta parece bastante extraña aquí - desplazando áreas de texto dentro de las áreas de texto desplazables - Estoy seguro de que es un error SO ... – blissapp

+0

No hice nada intencionalmente para tener dos áreas de prueba de desplazamiento ... Simplemente surgió así .. I también estoy sorprendido con esto ... :) –