Domanda

Ho un XML simile al di sotto, che deve essere risolto utilizzando il campo data.

<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 (ordine crescente per esempio), indipendentemente dal fatto che la data è in Node1 o Nodo2. In realtà, in codice Java Ho due liste separate, una con oggetti Nodo 1 e l'altro con gli oggetti Node2. Posso ordinare l'elenco in qualsiasi ordine a parte all'interno del Java. Ma ho bisogno di avere le date ordinati a prescindere dei nodi è che appaiono sul XML. Qual è l'approccio migliore per risolvere in questo modo in Java?

In realtà sto usando Castor per il marshalling gli oggetti Java in XML. Se sai che questo può essere fatto con Castor, che sarà grande!

È stato utile?

Soluzione

userei XSLT, ha probs con l'ordinamento date che avrete bisogno di tutto il lavoro, 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>

Altri suggerimenti

Se vuoi il risultato del genere ad essere un unico elenco, ordinato per data, allora devi mettere tutti i nodi in un unico elenco di array. Se i due tipi (node1 e node2) estendere una classe base comune, è possibile utilizzare Generics di Java per voi lista.

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 si dovrà scrivere il proprio comparatore. ecco un esempio di quello che si potrebbe usare se i tipi di nodi hanno una classe di super-comune che tiene 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 possono essere trovate qui se volete qualsiasi informazioni su di esso il proprio comportamento.

Utilizzando il metodo di cui sopra, è facile vedere come si potrebbe scrivere qualsiasi tipo di funzione di confronto per modificare il comportamento del vostro tipo. Si potrebbe anche scrivere come molte classi comparatore personalizzato come ci si piacimento in modo che li si possa cambiare in fase di esecuzione. Spero che sia di aiuto! :)

Ho usato XSLT e Xalan.

L'XSL è come sotto .. 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 *************");
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top