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

基于有序列表解析XML:Java DOM递归实现的节点关联疑问

问题描述

需要将以下CSV格式的层级数据:

order, xml_parent, xml_field
1,Identification,Id
2,Identification.Name,LastName
3,Identification.Name,FirstName
4,Identification.OfficialAddress,StreetName
5,Identification.OfficialAddress,StreetNumber
7,Identification.OfficialAddress,PostalCode
8,Identification.OfficialAddress,City
9,Identification.OfficialAddress,Country
10,Identification.Nationality
13,ReasonIntroduction.AskSomething,FromDate
14,ReasonIntroduction.AskMore,FirstTime

转换为指定结构的XML:

<root>
    <Identification>
        <Id>1</Id>
        <Name>
            <LastName>x</LastName>
            <FirstName>x</FirstName>
        </Name>
        <OfficialAddress>
            <StreetName>Fifth av.</StreetName>
            <StreetNumber>5</StreetNumber>
            <PostalCode>3212</PostalCode>
            <City>3212</City>
            <Country>UK</Country>
         </OfficialAddress>
         <Nationality>Qatar</Nationality>
    </Identification>
    <ReasonIntroduction>
        <AskSomething>true</AskSomething>
        <AskMore>true</AskMore>
    </ReasonIntroduction>
</root>

计划用Java DOM解析实现,希望采用递归方式而非循环,但不清楚如何分组同层级元素(比如将Identification.Name下的LastName和FirstName纳入同一个<Name>节点),已有部分代码片段:

List<String> parentList = Arrays.asList(parentXmlName.split("\\.", -1));

Element parentElement = document.createElement(field.getXmlParentName());
Element element = document.createElement(field.getXmlName());
element.setTextContent(field.getValue());
parentElement.appendChild(element);
递归实现思路

1. 先将扁平CSV数据转换为树形映射

递归的核心前提是有清晰的层级结构,所以第一步要把CSV的扁平数据转换成树形结构的映射(用Map<String, Object>模拟:节点名作为key,值如果是String表示叶子节点的文本,Map表示子节点集合)。

示例实现代码:

// 假设你已有存储字段的实体类
class Field {
    private String xmlParent;
    private String xmlField;
    private String value;
    // 省略getter、构造方法
}

// 构建树形映射的方法
private Map<String, Object> buildTreeMap(List<Field> fields) {
    Map<String, Object> rootMap = new HashMap<>();
    for (Field field : fields) {
        // 拆分父路径为节点数组
        String[] parentNodes = field.getXmlParent().split("\\.", -1);
        Map<String, Object> currentMap = rootMap;
        
        // 遍历父路径,创建中间节点的Map
        for (String nodeName : parentNodes) {
            currentMap = currentMap.computeIfAbsent(nodeName, k -> new HashMap<String, Object>());
        }
        
        // 将当前字段作为叶子节点加入最终的父Map
        currentMap.put(field.getXmlField(), field.getValue());
    }
    return rootMap;
}

这个方法会把所有字段按层级嵌套,比如Identification.Name.LastName会被整理为rootMap -> "Identification" -> "Name" -> "LastName": "x"。

2. 递归遍历树形映射生成XML节点

有了树形映射后,编写递归方法遍历结构,逐个创建DOM元素:

private void buildXmlFromTree(Document doc, Element parentElement, Map<String, Object> nodeMap) {
    for (Map.Entry<String, Object> entry : nodeMap.entrySet()) {
        String nodeName = entry.getKey();
        Object value = entry.getValue();
        
        Element currentElement = doc.createElement(nodeName);
        
        if (value instanceof String) {
            // 叶子节点:设置文本内容
            currentElement.setTextContent((String) value);
            parentElement.appendChild(currentElement);
        } else if (value instanceof Map) {
            // 非叶子节点:递归处理子节点
            parentElement.appendChild(currentElement);
            buildXmlFromTree(doc, currentElement, (Map<String, Object>) value);
        }
    }
}

3. 整合流程生成完整XML

将预处理、递归生成逻辑与DOM初始化整合:

// 假设已读取到所有Field的列表List<Field> fieldList
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();

// 创建根节点<root>
Element rootElement = doc.createElement("root");
doc.appendChild(rootElement);

// 构建树形映射
Map<String, Object> treeMap = buildTreeMap(fieldList);

// 递归生成XML结构
buildXmlFromTree(doc, rootElement, treeMap);

// 后续可将doc输出为XML字符串或文件,此处省略输出逻辑

关键说明

  • 递归的核心是先构建层级数据结构,树形映射已经把同层级元素归到了同一个父节点下,无需手动跟踪"下一个元素",递归只需专注于当前节点的子节点处理即可。
  • 这种方式把数据整理和节点生成解耦,逻辑更清晰,也完全符合递归的思想。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:05:26