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>

我想根据日期(比如升序)对 XML 进行排序,无论日期是在 Node1 下还是 Node2 下。实际上,在 Java 代码中,我有两个单独的列表,一个带有 Node1 对象,另一个带有 Node2 对象。我可以在java中以任何顺序单独对列表进行排序。但是我需要对日期进行排序,而不管它出现在 XML 上的节点如何。在 Java 中以这种方式排序的最佳方法是什么?

实际上,我正在使用 Castor 将 java 对象编组为 XML。如果您知道这可以用 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

如果您希望排序结果为单个列表,按日期排序,则必须将所有节点放入单个数组列表中。如果这两种类型(节点 1 和节点 2)扩展了一个公共基类,您可以使用 Java 的泛型为您列出。

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

如果这两种节点类型不是从一个公共类继承的,您可以简单地使用一个对象列表。

现在您必须编写自己的比较器。如果节点类型确实有一个包含 Date 字段的公共超类,这是一个您可以使用的示例。

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 。

使用上述方法,很容易看出如何编写任何类型的比较函数来更改排序行为。您还可以编写任意数量的自定义 Comparator 类,以便您可以在运行时切换它们。希望这可以帮助!:)

于 2010-05-26T23:19:43.613 回答
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 回答