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

Jackson XmlMapper反序列化时XML属性处理异常求助

解决Jackson XML转JsonNode后属性变子标签的问题

核心原因

Jackson XML模块默认会把XML属性转为带@前缀的JsonNode节点,但如果配置不当,反序列化时属性会丢失前缀,导致序列化回XML时被识别为子标签而非属性。

解决方案

通过配置XmlMapper,明确标记XML属性的前缀,并确保序列化时识别该前缀为属性:

  • 初始化配置正确的XmlMapper
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.DeserializationFeature;

// 创建XML模块并配置
JacksonXmlModule xmlModule = new JacksonXmlModule();
// 禁用根节点包装,避免额外嵌套
xmlModule.setDefaultUseWrapper(false);

XmlMapper xmlMapper = XmlMapper.builder(xmlModule)
    // 明确设置XML属性在JsonNode中的前缀为@
    .configure(FromXmlParser.Feature.ATTR_PREFIX, "@")
    // 禁用根节点序列化包装
    .configure(SerializationFeature.WRAP_ROOT_VALUE, false)
    // 禁用根节点反序列化解包
    .configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false)
    .build();
  • 处理Xml转JsonNode及修改
    原XML示例:
<root>
  <innerField1 innerField1Attribute="originalValue">some content</innerField1>
</root>

转成JsonNode后,属性会被标记为@innerField1Attribute:

{
  "innerField1": {
    "@innerField1Attribute": "originalValue",
    "#text": "some content"
  }
}

修改时直接操作带@前缀的节点:

JsonNode rootNode = xmlMapper.readTree(xmlString);
ObjectNode innerFieldNode = (ObjectNode) rootNode.get("innerField1");
// 修改属性值
innerFieldNode.put("@innerField1Attribute", "newValue");
  • 转回XML
String modifiedXml = xmlMapper.writeValueAsString(rootNode);

输出的XML会保留属性:

<root>
  <innerField1 innerField1Attribute="newValue">some content</innerField1>
</root>

注意事项

  • 必须确保JsonNode中属性节点以@开头,否则序列化时会被当作子标签
  • 2.11.1版本的Jackson中FromXmlParser.Feature.ATTR_PREFIX默认值为@,但显式配置可避免环境差异导致的问题
  • 不要随意修改属性前缀规则,否则会破坏Jackson对XML属性的识别逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:22:19