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

Jackson XML反序列化为Java LinkedTreeMap结果不符问题咨询

解决Jackson XML转Map时结构不符合预期的问题

我明白你遇到的困扰——用Jackson的XmlMapper把这段XML转成LinkedTreeMap时,实际得到的结构和你预想的不一样。先帮你拆解下问题原因,再给你几个可行的解决方案:

问题根源

默认情况下Jackson XML反序列化有两个核心行为会导致结构不符:

  1. 标签大小写保留:XML里的<Properties>标签会被直接映射成Map的键"Properties"(而不是你预期的小写"properties");
  2. 重复子节点的默认处理:<runList>下的多个<runID>会被包裹在一个以"runID"为键的List里,默认得到的结构大概是:
    { "Properties": { "runList": { "runID": [6656, 6657] } } }
    
    这和你想要的索引式Map或扁平化结构有明显差异。

解决方案1:直接配置XmlMapper并调整结构

如果你不想定义POJO,只想直接转成Map并调整为预期结构,可以这么操作:

步骤1:配置XmlMapper忽略键的大小写

先让Mapper支持大小写不敏感的键映射,把"Properties"自动转为"properties":

XmlMapper xmlMapper = XmlMapper.builder()
    .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
    .build();

步骤2:转换并手动调整结构

把默认得到的Map里的runID列表转成索引式Map:

String xmlContent = "<Properties> <runList> <runID>6656</runID> <runID>6657</runID> </runList> </Properties>";
Map<String, Object> originalMap = xmlMapper.readValue(xmlContent, Map.class);

// 调整为你预期的结构
Map<String, Object> properties = (Map<String, Object>) originalMap.get("properties");
Map<String, Object> runList = (Map<String, Object>) properties.get("runList");
List<Integer> runIDs = (List<Integer>) runList.get("runID");

Map<String, Object> targetRunList = new LinkedHashMap<>();
for (int i = 0; i < runIDs.size(); i++) {
    targetRunList.put(String.valueOf(i), runIDs.get(i));
}

properties.put("runList", targetRunList);

// 最终结构:{ properties => { runList => { 0=> 6656, 1=> 6657 } } }
System.out.println(originalMap);

解决方案2:用POJO精准控制结构(更推荐)

如果希望序列化逻辑更可控,先定义匹配XML的POJO,再转成目标Map结构:

定义匹配XML的POJO

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import java.util.List;

public class Properties {
    // 禁用runList的包装,直接把runID作为列表元素
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Integer> runID;

    // Getter和Setter
    public List<Integer> getRunID() {
        return runID;
    }

    public void setRunID(List<Integer> runID) {
        this.runID = runID;
    }
}

反序列化并转换为目标Map

XmlMapper xmlMapper = new XmlMapper();
Properties props = xmlMapper.readValue(xmlContent, Properties.class);

// 构建你想要的Map结构
Map<String, Object> resultMap = new LinkedHashMap<>();
Map<String, Object> runListMap = new LinkedHashMap<>();
for (int i = 0; i < props.getRunID().size(); i++) {
    runListMap.put(String.valueOf(i), props.getRunID().get(i));
}
resultMap.put("properties", Map.of("runList", runListMap));

// 输出结果即为你预期的结构
System.out.println(resultMap);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:28:36