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

如何配置Jackson2 XmlMapper自动识别重复XML子节点并转为命名数组

问题描述

我用这段代码把XML转成JSON:

ObjectMapper xmlMapper = new XmlMapper();
JsonNode jsonNode = xmlMapper.readTree("<fakeRoot>" + xmlText + "</fakeRoot>");
String jsonString = jsonNode.toString();
System.out.println("jsonString = " + jsonString);

其中xmlText的内容是:

<a>
    <b>
        <c>xxxx</c>
    </b>
    <b>
        <c>yyyy</c>
    </b>
    <b>
        <c>zzzz</c>
    </b>
</a>

我想要生成的JSON是这样的:

{
  "a": {
    "b": [
      { "c": "xxxx" },
      { "c": "yyyy" },
      { "c": "zzzz" }
    ]
  }
}

但XmlMapper实际返回的却是错误的结果:

{"a":{"b":{"c":"zzzz"}}}

请问这是为什么?怎么配置XmlMapper生成预期的JSON(不用给"a"、"b"、"c"写Java类)?如何让XmlMapper自动识别重复的XML子节点并转成数组?

原因分析

XML本身没有数组的概念,重复的同名节点只是同一元素的多次出现。Jackson的XmlMapper默认处理逻辑是:遇到重复的同名节点时,后面的节点会覆盖前面的,最终只保留最后一个节点的内容,这就是结果里只有zzzz的原因。

解决方案

要让XmlMapper自动把重复节点转为数组,不需要定义Java类,只需要调整XmlMapper的配置即可:

  1. 创建JacksonXmlModule并关闭默认的包装器行为,让重复节点不会被当作包装器内的元素处理;
  2. 可选:启用ACCEPT_SINGLE_VALUE_AS_ARRAY特性,确保单个节点也能被识别为数组(如果需要单节点场景也生成数组的话);
  3. 用配置好的模块初始化XmlMapper。

修改后的代码如下:

JacksonXmlModule module = new JacksonXmlModule();
// 关闭默认包装器,让重复节点直接转为数组
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
// 启用该特性,确保单个节点也能被转为数组(可选)
xmlMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

// 后续解析代码不变
JsonNode jsonNode = xmlMapper.readTree("<fakeRoot>" + xmlText + "</fakeRoot>");
String jsonString = jsonNode.toString();
System.out.println("jsonString = " + jsonString);

这样配置后,XmlMapper会自动识别重复的<b>节点,将其转为JSON数组,生成你预期的结果。如果不需要单个节点转数组,可以去掉enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)这一行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:33:24