在Java中对XML进行排序

在Java中对XML进行排序,java,xml,castor,Java,Xml,Castor,我有一个类似于下面的XML,需要使用date字段对其进行排序 <root> <Node1> <date></date> </Node1> <Node1> <date></date> </Node1> <Node1> <date></date>

我有一个类似于下面的XML,需要使用date字段对其进行排序

<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>
public class NodeComparator implements Comparator<Node> {
    @Override
    public int compare(Node node1, Node node2) {
        return node1.getDate().compare(node2.getDate());
    }
}

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


实际上,我正在使用Castor将java对象封送到XML。如果你知道用Castor可以做到这一点,那就太好了

我会使用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>

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

List<Node> nodes = new ArrayList<Node>();
nodes.add(node1);
nodes.add(node2);
Node[] nodeArrayToSort = nodes.toArray();
如果您想了解有关上述方法行为的任何其他信息,可以找到该方法的javadoc


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

我还认为XSL排序会更好更快

检查以下链接

谢谢。

我使用了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>

XML“意味着”是一个集合,所以按升序排序数据并不“意味着”有用…@blissapp-顺序是XML的基础,抽象模型是一个序列。XPath2.0/xquery的基础。也许您考虑的是关系数据?@mdma XML 1.0规范不能保证元素顺序。格式良好的定义明确指出属性是无序的,但没有说明元素。@app因此,XPath position()函数本质上没有定义它返回哪个节点?这是荒谬的。即使是旧的DTD也会考虑元素顺序——有些表达式只有在顺序已知或结果识别器变得不确定时才能解析。属性顺序不是模型的一部分,但元素顺序是模型的基础。@mdma XPath、XSLT等都继承自XML信息集建议,该建议规定子项是按文档顺序排列的子信息项列表。在原始XML中,情况并非如此。很酷,很高兴看到如何在Java中实现它。你的回答在这里看起来很奇怪-滚动文本区域内滚动文本区域-我确信这是一个非常错误…我没有故意做任何事情来拥有两个滚动测试区域..只是像这样出现。。我也对此感到惊讶:)我有相同的案例,但日期格式不同,比如2015-12-27T16:44:07,那么在这种情况下怎么做呢
<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>
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 *************");
  }
}