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

如何借助XSD解析嵌套XML并在Java中构建结构化HashMap列表

实现方案

核心思路

针对嵌套XML,我们需要扁平化标签路径(用.分隔父节点与子节点)作为HashMap的key,标签文本作为value;同时定位XML中代表“行”的重复节点(比如业务数据中的<record>或<user>),每个这样的节点对应一个HashMap,最终收集为List<HashMap<String, String>>。

完整代码实现

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class XmlToHashMapList {
    public static void main(String[] args) {
        try {
            // 初始化DOM解析器,过滤空白和注释节点
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setIgnoringElementContentWhitespace(true);
            factory.setIgnoringComments(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new File("your-data.xml"));
            doc.normalize();

            // 定位到代表单行数据的重复节点(需根据你的XML结构修改标签名)
            NodeList rowNodes = doc.getElementsByTagName("user");
            List<HashMap<String, String>> recordList = new ArrayList<>();

            // 遍历每个行节点,构建对应的HashMap
            for (int i = 0; i < rowNodes.getLength(); i++) {
                Node rowNode = rowNodes.item(i);
                HashMap<String, String> record = new HashMap<>();
                // 递归遍历子节点,扁平化路径并填充数据
                traverseNode(rowNode, "", record);
                recordList.add(record);
            }

            // 测试输出结果
            for (HashMap<String, String> map : recordList) {
                System.out.println(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 递归遍历节点,扁平化路径并填充HashMap
     * @param node 当前处理的节点
     * @param parentPath 父节点的路径(用于拼接当前节点的完整路径)
     * @param record 要填充的HashMap对象
     */
    private static void traverseNode(Node node, String parentPath, HashMap<String, String> record) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            // 拼接当前节点的完整路径
            String currentPath = parentPath.isEmpty() 
                ? element.getTagName() 
                : parentPath + "." + element.getTagName();

            // 检查当前节点是否包含子元素
            NodeList childNodes = element.getChildNodes();
            boolean hasChildElements = false;
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node child = childNodes.item(i);
                if (child.getNodeType() == Node.ELEMENT_NODE) {
                    hasChildElements = true;
                    traverseNode(child, currentPath, record);
                }
            }

            // 如果是叶子节点(无子元素),提取文本内容存入HashMap
            if (!hasChildElements) {
                String text = element.getTextContent().trim();
                if (!text.isEmpty()) {
                    record.put(currentPath, text);
                }
            }
        }
    }
}

代码说明

  1. 解析器配置:通过setIgnoringElementContentWhitespace和setIgnoringComments过滤干扰节点,避免空文本影响数据提取。
  2. 行节点定位:修改getElementsByTagName("user")中的标签名,替换为你XML中代表单行数据的重复节点(比如<order>、<product>)。
  3. 递归遍历逻辑:traverseNode方法自动拼接嵌套标签的路径,仅提取叶子节点的文本内容,确保HashMap的key是唯一的扁平化路径。

示例输出(对应嵌套XML)

假设你的XML结构如下:

<root>
  <user>
    <id>1</id>
    <name>Alice</name>
    <contact>
      <email>alice@test.com</email>
      <phone>123456</phone>
    </contact>
  </user>
  <user>
    <id>2</id>
    <name>Bob</name>
    <contact>
      <email>bob@test.com</email>
      <phone>654321</phone>
    </contact>
  </user>
</root>

运行代码后,输出的List每个元素为:

{id=1, name=Alice, contact.email=alice@test.com, contact.phone=123456}
{id=2, name=Bob, contact.email=bob@test.com, contact.phone=654321}

扩展处理

  • 提取属性:若需要提取XML元素的属性,可在traverseNode方法中添加属性遍历逻辑,比如:
    NamedNodeMap attrs = element.getAttributes();
    for (int j = 0; j < attrs.getLength(); j++) {
        Attr attr = (Attr) attrs.item(j);
        String attrKey = currentPath + "@" + attr.getName();
        record.put(attrKey, attr.getValue());
    }
    
  • XSD约束校验:如果需要遵循XSD的字段约束,可在解析完成后添加校验逻辑,确保HashMap包含必填字段。

内容的提问来源于stack exchange,提问作者Yashwin.L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:26:28