我试图通过对Elements进行分组来修改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,所以我只剩下选项就是修改文件以对元素进行分组。它只是一个样本,实际文件比这个和更多的元素大得多。
注意:我可以编写代码,但无法找到实现此目的的任何方法。任何观点或想法都是欢迎的:)
答案 0 :(得分:1)
您需要做几件事。
现在,使用JAXB将XML文件读入List<Article>
,其中包含源XML中的所有文章。
然后,创建一个地图。然后遍历List并将每个项目添加到Map(map.put(article,article)
)。如果地图已包含该文章,则抓取它并更新其媒体部分。例如:map.get(currentArticle).getMedia.addAll(currentArticle.getMedia())
完成后,您可以将Java编组回XML。
注意:使用Map而不是Set的原因是你需要能够检索对象并修改它在一个你不能的Set中。
答案 1 :(得分:0)
为了扩展David的答案,你不一定需要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。 / p>