7

以下のような 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 にマーシャリングするために Castor を使用しています。これが Castor で実行できることを知っていれば、それはすばらしいことです。

4

4 に答える 4

2

私は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>
于 2010-05-26T22:36:55.600 に答える
1

また、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

ありがとう。

于 2010-05-27T06:37:18.313 に答える
0

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 *************");
  }
}
于 2010-05-27T20:15:16.270 に答える
0

並べ替えの結果を日付で並べ替えた単一のリストにしたい場合は、すべてのノードを配列の単一のリストに入れる必要があります。2 つのタイプ (node1 と node2) が共通の基本クラスを拡張する場合、リストに Java の Generics を使用できます。

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

2 つのノード タイプが共通のクラスから継承されていない場合は、単純にオブジェクトのリストを使用できます。

ここで、独自の Comparator を作成する必要があります。以下は、ノード タイプに Date フィールドを保持する共通のスーパー クラスがある場合に使用できる例です。

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

これで、カスタム コンパレータとすべてのノードを含む配列ができたので、リストを並べ替える Java コードは 1 行です。

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

上記のメソッドの javadoc は、その動作に関する追加情報が必要な場合は、ここにあります。

上記の方法を使用すると、任意のタイプの比較関数を記述してソートの動作を変更する方法を簡単に確認できます。実行時に切り替えることができるように、必要な数のカスタム Comparator クラスを作成することもできます。お役に立てれば!:)

于 2010-05-26T23:19:43.613 に答える