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

如何解析含重复标签的XML并将数据存入List(Java EE 5)

解析重复标签XML时仅获取第一个值的解决方案

问题场景

现有如下结构的XML,需要将所有<abc:Order>和<abc:Name>的值分别存入对应的List,但当前解析代码仅能获取第一个值。

原XML结构:

<abc:Body>
   <abc:AssyData>
     <abc:Order>1</abc:Order>
     <abc:Name>A</abc:Name>
   </abc:AssyData>
   <abc:AssyData>
     <abc:Order>2</abc:Order>
     <abc:Name>B</abc:Name>
   </abc:AssyData>
   <abc:AssyData>
     <abc:Order>3</abc:Order>
     <abc:Name>C</abc:Name>
   </abc:AssyData>
</abc:Body>

当前代码输出:

List<String> orders = [1]
List<String> names = [A]

期望输出:

List<String> orders = [1,2,3]
List<String> names = [A,B,C]

原代码问题分析

原代码的核心错误是仅遍历了<abc:Body>节点(通常XML中只有一个该节点),然后直接调用item(0)获取第一个<abc:Order>和<abc:Name>的值,完全没有遍历所有包含完整数据的<abc:AssyData>节点,导致只能拿到第一组数据。

原代码:

String order = null;
String name = null;
List<String> orders = new ArrayList<String>();
List<String> names = new ArrayList<String>();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
     dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
     DocumentBuilder db = dbf.newDocumentBuilder();
     Document doc = db.parse(new File(IDOC));//IDOC是磁盘上的XML文件
     doc.getDocumentElement().normalize();
     NodeList list = doc.getElementsByTagName("abc:Body");
     for (int temp = 0; temp < list.getLength(); temp++) {
       Node node = list.item(temp);
       if(node.getNodeType() == Node.ELEMENT_NODE) {
          Element element = (Element) node;
          orders.add(element.getElementsByTagName("abc:Order").item(0).getTextContent());
          names.add(element.getElementsByTagName("abc:Name").item(0).getTextContent());
       }
     }
} catch (Exception e) {
     e.printStackTrace();
}
System.out.println(orders);
System.out.println(names);

修改后的代码

核心调整为:直接获取所有<abc:AssyData>节点并遍历,从每个节点中提取对应的数据存入List。

String order = null;
String name = null;
List<String> orders = new ArrayList<String>();
List<String> names = new ArrayList<String>();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
    dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    // 开启命名空间支持,避免前缀abc导致节点匹配失败
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(new File(IDOC));//IDOC是磁盘上的XML文件
    doc.getDocumentElement().normalize();

    // 获取所有abc:AssyData节点,每个节点对应一组Order和Name
    NodeList assyDataList = doc.getElementsByTagName("abc:AssyData");
    for (int i = 0; i < assyDataList.getLength(); i++) {
        Node assyNode = assyDataList.item(i);
        if (assyNode.getNodeType() == Node.ELEMENT_NODE) {
            Element assyElement = (Element) assyNode;
            // 提取当前AssyData下的Order值,添加空判断避免空指针
            Node orderNode = assyElement.getElementsByTagName("abc:Order").item(0);
            if (orderNode != null) {
                orders.add(orderNode.getTextContent().trim());
            }
            // 提取当前AssyData下的Name值
            Node nameNode = assyElement.getElementsByTagName("abc:Name").item(0);
            if (nameNode != null) {
                names.add(nameNode.getTextContent().trim());
            }
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(orders);
System.out.println(names);

关键说明

  1. 命名空间支持:添加dbf.setNamespaceAware(true);确保解析器能正确识别带前缀的节点,避免因命名空间问题找不到<abc:AssyData>等节点。
  2. 遍历数据节点:直接遍历所有<abc:AssyData>节点,每个节点对应一组完整的Order和Name数据,保证能收集到全部值。
  3. 空值防护:添加节点非空判断,避免XML中缺失某个标签时触发空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:19:57