Сортировка XML в Java

У меня есть подобное 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, который будет великим!

7
задан Abdollah 29 September 2019 в 13:13
поделиться

4 ответа

Я бы использовал 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>
2
ответ дан 7 December 2019 в 16:39
поделиться

Я также думаю, что 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

спасибо.

1
ответ дан 7 December 2019 в 16:39
поделиться

Если вы хотите, чтобы результат сортировки был единым списком, отсортированным по дате, вы должны поместить все узлы в один список массива. Если два типа (node1 и node2) расширяют общий базовый класс, вы можете использовать Java Generics для своего списка.

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, сколько захотите, чтобы вы могли переключать их во время выполнения.Надеюсь это поможет! :)

0
ответ дан 7 December 2019 в 16:39
поделиться

Я использовал XSLT и XALAN.

XSL-код выглядит следующим образом. Дата имеет формат мм / дд / гггг

<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 *************");
  }
}
0
ответ дан 7 December 2019 в 16:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: