题
我有一个类似于下面的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来完成,那就太好了!
解决方案
我会使用XSLT,它具有与排序日期的概率
<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的generics for列表。
List<Node> nodes = new ArrayList<Node>();
nodes.add(node1);
nodes.add(node2);
Node[] nodeArrayToSort = nodes.toArray();
如果两个节点类型不从公共类继承,则可以简单地使用对象列表。
现在,您将必须编写自己的比较器。如果节点类型确实具有保存日期字段的通用超级类,则可以使用以下一个示例。
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 *************");
}
}
不隶属于 StackOverflow