如何使用Java按XML的ID、NAME、CITY标签分组MEDIA元素?
用Java实现XML Article节点按ID/NAME/CITY分组的方案
我来给你详细讲讲怎么实现这个需求,步骤清晰,代码直接能用:
核心思路
我们需要先解析XML,把每个Article的ID、NAME、CITY作为分组标识,把相同标识的MEDIA元素合并到同一个Article节点下。具体分三步:
- 解析输入XML,提取每个Article的分组字段和MEDIA元素
- 用Map做分组容器,键是包含三个分组字段的自定义对象,值是对应的MEDIA列表
- 根据分组结果生成新的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
相关产品推荐
相关产品推荐

