You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Java按XML的ID、NAME、CITY标签分组MEDIA元素?

用Java实现XML Article节点按ID/NAME/CITY分组的方案

我来给你详细讲讲怎么实现这个需求,步骤清晰,代码直接能用:

核心思路

我们需要先解析XML,把每个Article的ID、NAME、CITY作为分组标识,把相同标识的MEDIA元素合并到同一个Article节点下。具体分三步:

  1. 解析输入XML,提取每个Article的分组字段和MEDIA元素
  2. 用Map做分组容器,键是包含三个分组字段的自定义对象,值是对应的MEDIA列表
  3. 根据分组结果生成新的XML结构

具体实现代码

这里我用JDOM2库来处理XML,它比Java原生DOM API更简洁易用。先给你完整代码,再逐个部分解释:

1. 先添加JDOM2依赖(Maven)

如果用Maven管理项目,先在pom.xml里加这个依赖:

<dependency>
    <groupId>org.jdom</groupId>
    <artifactId>jdom2</artifactId>
    <version>2.0.6.1</version>
</dependency>

2. 完整Java代码

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

public class XmlArticleGrouper {

    public static void main(String[] args) {
        try {
            // 解析输入XML文件(替换成你的输入文件路径)
            SAXBuilder saxBuilder = new SAXBuilder();
            Document document = saxBuilder.build(new File("input.xml"));
            Element root = document.getRootElement();
            List<Element> allArticles = root.getChildren("Article");

            // 用HashMap做分组:key是分组标识,value是该组的所有MEDIA元素
            Map<GroupKey, List<Element>> articleGroups = new HashMap<>();

            for (Element article : allArticles) {
                // 提取分组的三个字段,trim掉前后空格避免分组错误
                String id = article.getChildTextTrim("ID");
                String name = article.getChildTextTrim("NAME");
                String city = article.getChildTextTrim("CITY");
                GroupKey groupKey = new GroupKey(id, name, city);

                // 提取当前Article下的所有MEDIA元素
                List<Element> mediaList = article.getChildren("MEDIA");

                // 把MEDIA元素加入对应分组:如果分组不存在就创建新的
                articleGroups.computeIfAbsent(groupKey, k -> new ArrayList<>()).addAll(mediaList);
            }

            // 构建新的XML文档
            Element newRoot = new Element(root.getName()); // 保留原根节点名称
            for (Map.Entry<GroupKey, List<Element>> entry : articleGroups.entrySet()) {
                GroupKey key = entry.getKey();
                List<Element> groupedMedias = entry.getValue();

                // 创建新的Article节点
                Element newArticle = new Element("Article");
                // 添加分组的三个核心字段
                newArticle.addContent(new Element("ID").setText(key.getId()));
                newArticle.addContent(new Element("NAME").setText(key.getName()));
                newArticle.addContent(new Element("CITY").setText(key.getCity()));
                // 添加所有归组的MEDIA元素
                newArticle.addContent(groupedMedias);

                newRoot.addContent(newArticle);
            }

            // 格式化输出新XML到文件(替换成你的输出文件路径)
            Document newDocument = new Document(newRoot);
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
            outputter.output(newDocument, new FileWriter("output.xml"));

            System.out.println("XML分组处理完成!结果已保存到output.xml");

        } catch (JDOMException | IOException e) {
            e.printStackTrace();
        }
    }

    // 自定义分组键类:必须重写equals和hashCode才能作为HashMap的键
    static class GroupKey {
        private final String id;
        private final String name;
        private final String city;

        public GroupKey(String id, String name, String city) {
            this.id = id;
            this.name = name;
            this.city = city;
        }

        // Getter方法
        public String getId() { return id; }
        public String getName() { return name; }
        public String getCity() { return city; }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            GroupKey groupKey = (GroupKey) o;
            return Objects.equals(id, groupKey.id) &&
                   Objects.equals(name, groupKey.name) &&
                   Objects.equals(city, groupKey.city);
        }

        @Override
        public int hashCode() {
            return Objects.hash(id, name, city);
        }
    }
}

关键细节说明

  • GroupKey类:这个类是分组的核心,必须重写equals()和hashCode(),这样HashMap才能正确识别相同的分组标识(比如两个不同的Article如果ID/NAME/CITY都一样,会被认为是同一个键)。
  • trim处理:用getChildTextTrim()而不是getChildText(),是为了避免因为字段前后的空格导致分组错误(比如"New York"和" New York "会被当成不同值)。
  • 保留原结构:JDOM2会完整保留MEDIA元素的所有子节点和属性,不用担心分组后丢失数据。
  • 空MEDIA处理:如果某个Article没有MEDIA元素,分组后对应的Article节点只会包含ID/NAME/CITY,不会有MEDIA节点,符合需求。

不用第三方库的替代方案(原生DOM)

如果不想依赖JDOM2,也可以用Java原生的DocumentBuilderFactory来解析和生成XML,不过代码会更繁琐一些,核心逻辑还是一样的:用Map分组,再重新构建XML结构。

内容的提问来源于stack exchange,提问作者Squeez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:01:42