Сортировка XML в Java
Я хотел бы отсортировать XML на основе даты (например, порядок ордера), независимо от того, находится ли дата под узлом Node1 или Node2. Фактически в Java-коде у меня есть два отдельных списка: один с объектами Node1 и другие с узлами Node2. Я могу сортировать список в любом порядке с помощью java. Но мне нужно, чтобы даты сортировались независимо от узлов, которые он использует в XML. Каков наилучший способ сортировки в Java? Actaully Я использую Castor для сортировки java-объектов в XML. Если вы знаете, что это может быть сделано с Castor, это будет здорово!
XML «предназначен», чтобы быть набором, поэтому сортировка данных в порядке возрастания «не предназначена», чтобы быть полезной .
@blissapp — Порядок имеет фундаментальное значение для XML, абстрактная модель — это последовательность. основа xpath 2.0 / xquery. Может быть, вы думаете о реляционных данных?
@mdma Спецификация XML 1.0 не гарантирует порядок элементов. Правильное определение определенно утверждает, что атрибуты неупорядочены, но ничего не говорит об элементах.
@blissapp Итак, функция XPath position () по сути не определена, к какому узлу она возвращается? Это просто абсурдно. Даже старое DTD учитывает порядок элементов — есть некоторые выражения, которые могут быть проанализированы, только когда порядок известен, или результирующий распознаватель становится недетерминированным. Порядок атрибутов не является частью модели, но порядок элементов является основополагающим для него.
@mdma XPath, XSLT и т. д. все унаследованы от рекомендации набора информации XML, в которой говорится, что дочерние элементы — это упорядоченный список дочерних информационных элементов в порядке документов. В сыром XML это не так.
@blisapp — в теории то, что вы говорите, правда, но на практике это не так. Re: «правильная форма . но ничего не говорит об элементах» — вот статья от developerWorks, в которой обсуждается этот момент (и приводит ваше утверждение в значительной степени дословно 🙂 ibm.com/developerworks/xml/library/x-eleord .html
именно то, что я имел в виду, используя кавычки вокруг «имел ввиду». XML «предназначен», чтобы быть набором, но почти каждый рассматривает его как восходящий порядок. Я уверен, что я тоже наткнулся на этот веб-сайт, когда искал спецификации XML для подтверждения своего утверждения, так что, возможно, немного виноват в плагиате здесь . простите меня, бм . 😉
4 ответа
Я бы использовал XSLT, у него есть проблемы с датами сортировки, которые вам нужно будет работать, простейшим способом, если вы можете управлять им, чтобы иметь отсортированный формат даты, например yyyymmdd
у меня тот же случай — но формат даты другой — как 2015-12-27T16: 44: 07, так как это можно сделать в этом случае
Я также считаю, что сортировка XSL будет лучше и быстрее.
Проверьте следующие ссылки,
Я использовал XSLT и XALAN.
XSL выглядит следующим образом. Дата имеет формат mm/dd/yyyy
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 *************"); >>
Круто, приятно видеть, как это сделать на Java. Ваш ответ выглядит довольно странно — прокрутка текстовых областей внутри прокручиваемых текстовых областей — я уверен, что это ТАКАЯ ошибка .
Я ничего не делал намеренно, чтобы иметь две тестовые области прокрутки .. Просто так получилось .. Я тоже удивлен этим .. 🙂
Если вы хотите, чтобы результат сортировки был единственным списком, отсортированным по дате, вы должны поместить все узлы в один список массива. Если два типа (node1 и node2) расширяют общий базовый класс, вы можете использовать Java Generics для вашего списка.
List nodes = new ArrayList(); nodes.add(node1); nodes.add(node2); Node[] nodeArrayToSort = nodes.toArray();
Если два типа node не наследуются от общего класса, вы можете просто использовать Список объектов.
Теперь вам придется написать свой собственный компаратор. вот пример того, который вы могли бы использовать, если типы node имеют общий суперкласс, который содержит поле Date.
public class NodeComparator implements Comparator < @Override public int compare(Node node1, Node node2) < return node1.getDate().compare(node2.getDate()); >>
Теперь, когда у вас есть свой пользовательский компаратор и ваш массив со всеми вашими узлами, это одна строка кода Java для сортировки списка.
Arrays.sort(nodeArrayToSort, new NodeComparator());
javadoc для вышеуказанного метода можно найти здесь, если вы хотите получить дополнительную информацию о его поведении.
Используя вышеуказанный метод, легко увидеть, как вы могли бы написать любую функцию сравнения, чтобы изменить поведение вашего типа. Вы также можете написать столько пользовательских классов Comparator, сколько захотите, чтобы вы могли переключать их во время выполнения. Надеюсь это поможет!:)
Ещё вопросы
- 1 Создание пустого файла в каталоге
- 1 сгруппировать и суммировать два столбца и установить как один столбец в пандах
- 0 добавление HTML выбора стран в несколько мест
- 1 Почему запуск веб-приложения приводит к ошибке дублирующегося файла DLL
- 0 MySQL запрос, который меняет идентификатор команды на имя команды и делает не пустым
- 0 Как загрузить jQuery перед кодом CSS?
- 0 ошибка загрузки изображения с классом php и curl
- 1 Массовая вставка текстового файла в SQL Server с помощью pymssql
- 0 Как получить MySQL диск записи в Java, если включен InnoDb
- 0 Как максимизировать и минимизировать div на клике в jquerymobile
- 0 Как отобразить только обновленные данные формы в angularjs?
- 1 Невозможно загрузить torchvision, несмотря на то, что он установлен
- 0 добавление данных в таблицу из базы данных
- 1 Метод установки не вызывается в Hadoop Mapper
- 1 ReaderWriterLock.UpgradeToWriterLock не генерирует исключение по истечении времени ожидания?
- 1 Дарт, как разобрать байты из строки
- 0 Как Javascript взаимодействует с HTML через document.getElementById?
- 1 Как установить значок на значок приложения программно?
- 1 PyQt: множественный QProcess и вывод
- 1 Получить изменение состояния Интернета, когда Wi-Fi подключен
- 0 Ошибка сегментации в определениях классов не может определить, где
- 1 Неожиданное поведение при программном переключении исключений в Android P и Q Beta
- 0 вычислить std :: расстояние между двумя std :: reverse_iterators
- 0 HTTP-фейсбук в PHP, возвращающий массив, а не JSON
- 0 Перемещение нижнего колонтитула, которое исчезает, когда вы достигаете конца
- 1 Google Drive REST API AppDataFolder не работает, если APK подписан
- 0 Задание Cron для запуска PHP-скрипта в течение 24 часов, затем остановите его
- 0 SQL: запрос отображает максимальную дату (первая и вторая максимальная дата) [дубликаты]
- 1 Удалите некоторые значения массива для утверждения (транспортир)
- 1 Использование ruamel.yaml для обновления блока yaml в файле yaml, который содержит несколько yaml
- 1 Облачная функция Firebase возвращает ВНУТРЕННЮЮ ошибку
- 0 Console.log и document.addEventListener не работает
- 1 Как скрыть значение параметра запроса в URL, используя Spring MVC
- 0 Angular не обновляет цикл из-за реализации $ mdDialog (Material Design)
- 0 Отобразите второй div после некоторой задержки и оставьте второй div видимым, если мышь находится над первым или вторым div
- 0 Цвет наложения JQuery FancyBox
- 0 Как это работает сценарии JQuery для загрузки содержимого Grom AJAX?
- 1 Действия в андроид студии не переключаются после нажатия кнопки
- 0 Переключить расширяемый фон при нажатии
- 0 Отзывчивый дизайн сайта больше не отзывчивый
- 0 Facebook API — реализация приглашения друзей, как на Quora
- 0 Редактирование ссылки на переданный аргумент не обновляет модель
- 0 Magento, неверные цены в корзине
- 1 Android GC собирает объект, если событие имеет сильную ссылку на приложение (почему это происходит?)
- 1 Десериализовать JSON C #
- 0 Счетчик продолжает повторять, пожалуйста, дайте ответ
- 1 Изменение семейства шрифтов в OpenCV Python с использованием PIL
- 1 gulp-imagemin jpegtran-bin не работает, когда я запускаю простую задачу
- 1 Строка заменяет логику
Programmatica
Recently I had a requirement to sort an XML document based on the tag names in the document.
You can sort it using XSLT, but this post tells you how to sort the XML nodes through Java.
Lets extend the com.sun.org.apache.xerces.internal.util.DOMUtil or org.apache.xerces.internal.util.DOMUtil class which has some basic utility methods. And I’m going to extend it by adding a method called sortChildNodes() .
This method sorts the children of the given node in descending or ascending order with the given Comparator. And it recurses upto the specified depth if available.
1 package com.googlepages.aanand.dom;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import org.w3c.dom.Node;
10 import org.w3c.dom.NodeList;
11 import org.w3c.dom.Text;
12
13 import com.sun.org.apache.xerces.internal.util.DOMUtil;
14
15 public class DOMUtilExt extends DOMUtil 16
17 /**
18 * Sorts the children of the given node upto the specified depth if
19 * available
20 *
21 * @param node -
22 * node whose children will be sorted
23 * @param descending -
24 * true for sorting in descending order
25 * @param depth -
26 * depth upto which to sort in DOM
27 * @param comparator -
28 * comparator used to sort, if null a default NodeName
29 * comparator is used.
30 */
31 public static void sortChildNodes(Node node, boolean descending,
32 int depth,Comparator comparator) 33
34 List nodes = new ArrayList();
35 NodeList childNodeList = node.getChildNodes();
36 if (depth > 0 && childNodeList.getLength() > 0) 37 for (int i = 0; i < childNodeList.getLength(); i++) 38 Node tNode = childNodeList.item(i);
39 sortChildNodes(tNode, descending, depth - 1,
40 comparator);
// Remove empty text nodes
41 if ((!(tNode instanceof Text))
42 || (tNode instanceof Text && ((Text) tNode)
43 .getTextContent().trim().length() > 1))
44 <
nodes.add(tNode);
45 >
46 >
47 Comparator comp = (comparator != null) ? comparator
48 : new DefaultNodeNameComparator();
49 if (descending)
50 51 //if descending is true, get the reverse ordered comparator
52 Collections.sort(nodes, Collections.reverseOrder(comp));
53 > else 54 Collections.sort(nodes, comp);
55 >
56
57 for (Iterator iter = nodes.iterator(); iter.hasNext();) 58 Node element = (Node) iter.next();
59 node.appendChild(element);
60 >
61 >
62
63 >
64
65 >
66
67 class DefaultNodeNameComparator implements Comparator 68
69 public int compare(Object arg0, Object arg1) 70 return ((Node) arg0).getNodeName().compareTo(
71 ((Node) arg1).getNodeName());
72 >
73
74 >
And I’m also removing the empty text nodes. If descending is set true, then a reverse ordering comparator is obtained from the Collections utility class.
The utility uses a default NodeName comparator if a comparator is not specified. Its sorts based on the name of the nodes in the DOM.
Writing a Comparator implementation is very simple, for example you may want to sort a document based on an attribute in the XML document.
class MyComparator3 implements Comparator
public int compare(Object arg0, Object arg1)
if (arg0 instanceof Element && arg1 instanceof Element) return ((Element) arg0).getAttribute("id").compareTo(
((Element) arg1).getAttribute("id"));
> else return ((Node) arg0).getNodeName().compareTo(
((Node) arg1).getNodeName());
>
>
>
Its a very simple class to sort the nodes in any way you want. Please comment on it, if you point out a problem with the utility.
Posted by Indian Lycan at 11:31 PM