Я пытаюсь изменить формат xml, сгруппировав элементы. В формате ниже будут использоваться первые три элемента статьи (ID, NAME и CITY). для группировки элементов MEDIA. Это означает, что если элементы (ID, NAME и CITY) имеют ту же информацию, что и другие три элемента в другой статье, то элементы MEDIA будут сгруппированы по элементам (ID, NAME и CITY).
Например:
Вход
<Article>
<ID>100</ID>
<NAME>A</NAME>
<CITY>XX</CITY>
<MEDIA>
<MEDIANAME>PPP</MEDIANAME>
<MEDIACOLOR>RED></MEDIACOLOR>
</MEDIA>
</Article>
<Article>
<ID>100</ID>
<NAME>A</NAME>
<CITY>XX</CITY>
<MEDIA>
<MEDIANAME>PPC</MEDIANAME>
<MEDIACOLOR>YELLOW></MEDIACOLOR>
</MEDIA>
</Article>
<Article>
<ID>101</ID>
<NAME>B</NAME>
<CITY>YY</CITY>
<MEDIA>
<MEDIANAME>PPX</MEDIANAME>
<MEDIACOLOR>BLACK></MEDIACOLOR>
</MEDIA>
</Article>
<Article>
<ID>101</ID>
<NAME>B</NAME>
<CITY>YY</CITY>
<MEDIA>
<MEDIANAME>PPZ</MEDIANAME>
<MEDIACOLOR>PURPLE></MEDIACOLOR>
</MEDIA>
</Article>
Выход
<Article>
<ID>100</ID>
<NAME>A</NAME>
<CITY>XX</CITY>
<MEDIA>
<MEDIANAME>PPP</MEDIANAME>
<MEDIACOLOR>RED></MEDIACOLOR>
</MEDIA>
<MEDIA>
<MEDIANAME>PPC</MEDIANAME>
<MEDIACOLOR>YELLOW></MEDIACOLOR>
</MEDIA>
</Article>
<Article>
<ID>101</ID>
<NAME>B</NAME>
<CITY>YY</CITY>
<MEDIA>
<MEDIANAME>PPX</MEDIANAME>
<MEDIACOLOR>BLACK></MEDIACOLOR>
</MEDIA>
<MEDIA>
<MEDIANAME>PPZ</MEDIANAME>
<MEDIACOLOR>PURPLE></MEDIACOLOR>
</MEDIA>
</Article>
Могу ли я узнать, как добиться этого с помощью Java? Я буду получать xml только в этом формате, поэтому мне остается только изменить файл, чтобы сгруппировать элементы. Это всего лишь образец, фактический файл намного больше, чем этот, и большее количество элементов.
Примечание: я могу писать код, но не могу найти подход к этому. Приветствуются любые точки зрения или идеи :)
@yole, как я могу взять ссылку на первые три элемента статьи, чтобы проверить другие на предмет той же информации, и добавить свои элементы МЕДИА, если они найдут какое-либо совпадение? Да, я умею читать XML. Группа данных в этом случае не может найти никакого способа. Да, я знаю, как записывать данные в xml. :) Запись данных в xml здесь не используется (уже есть xml), во-вторых, можете ли вы сказать, читаете ли вы xml, как мы можем сделать эти группы? :)




Вам нужно сделать несколько вещей.
Теперь используйте JAXB, чтобы прочитать XML-файл на List<Article>, который будет содержать все статьи в вашем исходном XML.
Затем создайте карту. Затем перейдите по списку и добавьте каждый элемент на карту (map.put(article,article)). Если карта уже содержит эту статью, вы берете ее и обновляете раздел мультимедиа. Например: map.get(currentArticle).getMedia.addAll(currentArticle.getMedia())
Когда вы закончите, вы можете снова преобразовать Java в XML.
NB: причина использования карты, а не набора, заключается в том, что вам нужно иметь возможность извлекать объект и изменять его, чего в наборе вы не можете.
Спасибо, что поделились, но никогда не использовал библиотеку JAXB. Хорошо, я попробую это использовать. Возможно ли, что вы могли бы поделиться каким-либо образцом кода для этого подхода?
Чтобы расширить ответ Дэвида, вам не обязательно нужен jaxb (хотя это может облегчить вашу жизнь). В вашем XML-файле отсутствует корневой узел, что приведет к возникновению исключения из-за недопустимого формата. Это должно быть похоже
<Articles>
<Article>...</Article>
...
</Articles>
Используя только стандартный java7, вы можете объявить объект XPath
private final XPath xpath = XPathFactory.newInstance().newXPath();
И используйте это в методе, который считывает ваш XML-документ в объекты Java следующим образом:
String file = "/path/to/your/xml/file.xml";
FileInputStream fis = new FileInputStream(file);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fis);
NodeList nl = (NodeList) xpath.evaluate("/Articles/Article", doc, XPathConstants.NODESET);
List<Article> articles = new ArrayList<>();
for (int i = 0; i < nl.getLength(); i++) {
articles.add(new Article(nl.item(i)));
}
List<Article> merged = mergeMedia(articles);
с классом Article, например
private class Article {
private String id;
private String name;
private String city;
private List<Media> media;
// getters, setters
public Article(Node node) throws Exception {
this.id = (String) xpath.evaluate("ID", node, XPathConstants.STRING);
this.name = (String) xpath.evaluate("NAME", node, XPathConstants.STRING);
this.city = (String) xpath.evaluate("CITY", node, XPathConstants.STRING);
this.media = new ArrayList<Media>();
media.add(new Media((Node) xpath.evaluate("MEDIA", node, XPathConstants.NODE)));
}
}
и аналогичный медиа-класс.
Реализуйте метод объединения объектов, как вы описали (mergeMedia(articles) в моем примере), возвращая List или какой-либо другой Collection, а затем конвертируйте его обратно в xml по мере необходимости.
Какая часть задачи представляет для вас проблему? Вы умеете читать файлы XML? Вы знаете, как сгруппировать данные в памяти? Вы знаете, как записывать данные в XML-файл?