2010-05-26 13 views
6

Ciao Ho un XML simile a sotto, che doveva essere ordinato usando il campo della data.Ordinamento di un XML in 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> 

Vorrei ordinare l'XML in base alla data (diciamo ordine crescente), indipendentemente dal fatto che la data è in Node1 o Nodo2. In realtà nel codice Java ho due liste separate, una con oggetti Node1 e altre con obiezioni Node2. Posso ordinare l'elenco in qualsiasi ordine all'interno di java. Ma ho bisogno di avere le date ordinate indipendentemente dai nodi che sta apperando sull'XML. Qual è l'approccio migliore per ordinare in questo modo in Java?

Actaully Sto usando Castor per il marshalling degli oggetti java in XML. Se sai che questo può essere fatto con Castor, sarà fantastico!

+0

Grazie! Justin .. –

+0

XML è "pensato" per essere un set, quindi l'ordinamento dei dati in ordine crescente non è "pensato" per essere utile ... – blissapp

+4

@blissapp - L'ordine è fondamentale per XML, il modello astratto è una sequenza . la base di xpath 2.0/xquery. Forse stai pensando ai dati relazionali? – mdma

risposta

2

userei XSLT, ha probs con l'ordinamento date che avrete bisogno di lavorare intorno, modo più semplice se si può controllare è quello di avere il formato della data ordinabile come 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> 
+0

Grazie .... ........ –

+0

ho lo stesso caso - ma il formato della data è diverso - come 2015-12-27T16: 44: 07, quindi come può essere fatto in quel caso –

0

Se si farebbe come il risultato del tipo di essere una singola lista, ordinati per data, allora devi mettere tutti i nodi in un unico elenco di array. Se i due tipi (nodo1 & nodo2) estendono una classe base comune, è possibile utilizzare l'elenco Generics di Java per l'utente.

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

Se i due tipi di nodi non ereditano da una classe comune, si può semplicemente utilizzare un elenco di oggetti.

Ora dovrai scrivere il tuo comparatore. ecco un esempio di quello che potresti usare se i tipi di nodi hanno una super classe comune che contiene il campo Data.

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

Ora che avete il vostro confronto personalizzato e il vostro array con tutti i nodi, si tratta di una sola riga di codice Java per ordinare l'elenco.

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

Javadoc per il metodo di cui sopra può essere trovato here se si desidera qualsiasi informazioni sul suo comportamento.

Utilizzando il metodo precedente, è facile vedere come è possibile scrivere qualsiasi tipo di funzione di confronto per modificare il comportamento del proprio ordinamento. Puoi anche scrivere tutte le classi di Comparatore personalizzate che desideri, in modo che tu possa cambiarle in fase di runtime. Spero che questo ti aiuti! :)

0

Ho usato XSLT e XALAN.

XSL è come indicato di seguito ..Data è del formato gg/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> 

e il codice Java è

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

Cool, è bello vedere come tiralo fuori in Java. La tua risposta sembra piuttosto strana qui: scorrere le aree di testo all'interno delle aree di testo scorrevoli - Sono sicuro che sia un insetto SO ... – blissapp

+0

Non ho fatto nulla intenzionalmente per avere due aree di test a scorrimento .. Mi sono appena avvicinato così ... Sono anche sorpreso da questo .. :) –