質問
以下に似たXMLがあり、日付フィールドを使用してソートする必要があります。
<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>
日付がnode1またはnode2に関係なく、日付(昇順など)に基づいてXMLを並べ替えたいと思います。実際、Javaコードには2つの個別のリストがあります。1つはnode1オブジェクトを使用し、もう1つはnode2オブジェクトを使用しています。 Java内の任意の順序でリストを並べ替えることができます。しかし、XMLに表示されているノードに関係なく、日付をソートする必要があります。 Javaでこのようにソートするための最良のアプローチは何ですか?
実際、私はJavaオブジェクトをXMLにマーシャリングするためにキャスターを使用しています。これがキャスターでできることを知っているなら、それは素晴らしいことです!
解決
私はXSLTを使用します。それは、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>
他のヒント
また、XSLの並べ替えはより良くて速いと思います。
次のリンクを確認してください。
http://www.codeproject.com/kb/xml/sorting_dates_in_xsl.aspx
http://www.xml.com/pub/a/2002/07/03/transform.html?page=2
http://forums.devx.com/showthread.php?t=4063
ありがとう。
ソートの結果を日付ごとにソートしたい場合は、すべてのノードを配列の単一のリストに入れる必要があります。 2つのタイプ(node1&node2)が共通のベースクラスを拡張する場合、Javaのgenerics for yourリストを使用できます。
List<Node> nodes = new ArrayList<Node>();
nodes.add(node1);
nodes.add(node2);
Node[] nodeArrayToSort = nodes.toArray();
2つのノードタイプが共通のクラスから継承されない場合は、単にオブジェクトのリストを使用できます。
これで、独自のコンパレータを書く必要があります。ノードタイプに日付フィールドを保持する共通のスーパークラスがある場合、使用できる例の例を次に示します。
public class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node node1, Node node2) {
return node1.getDate().compare(node2.getDate());
}
}
カスタムコンパレータとすべてのノードを含む配列があるので、リストをソートするのはJavaコードの単一行です。
Arrays.sort(nodeArrayToSort, new NodeComparator());
上記の方法のJavadocを見つけることができます ここ その動作に関する追加情報が必要な場合。
上記の方法を使用すると、あらゆる種類の比較関数を書くためにどのように書くことができるかを簡単に確認して、ソートの動作を変更します。また、実行時に切り替えることができるように、カスタムコンパレータのクラスを多く書くこともできます。お役に立てれば! :)
XSLTとXalanを使用しました。
XSLは以下のとおりです。日付は形式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>
そして、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 *************");
}
}