如何分组XML标签

时间:2018-03-11 17:06:32

标签: java xml

我试图通过对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,所以我只剩下选项就是修改文件以对元素进行分组。它只是一个样本,实际文件比这个和更多的元素大得多。

注意:我可以编写代码,但无法找到实现此目的的任何方法。任何观点或想法都是欢迎的:)

2 个答案:

答案 0 :(得分:1)

您需要做几件事。

  1. 您需要将XML读入Java。有一个名为JAXB的库可以做到这一点。 JAXB将帮助您对XML进行编组和解组。
  2. 您需要定义信息模型。通过它的外观,你有一个名为Article的类,其中有3个(字符串)字段,称为id,name和city,它们共同构成该类实例的唯一标识符。然后,您有一个Media对象列表,每个对象都由名称和颜色组成。
  3. 在您的信息模型中,您需要覆盖equals()和hashcode()函数,以便在Article类的2个实例具有相同的3个id,name和city时找到相等。
  4. 现在,使用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>