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

Jackson XML解析误取属性而非标签的问题排查与解决

解决Jackson解析XML时混淆xsi:type属性与内部type标签的问题

问题场景

给定如下XML文件:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<nms:nmsDocument xmlns:nms="http://www.nms.com/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <nms:nmsObject xsi:type="nms:Test">
        <nms:type>
            <nms:domainValue>
                <nms:name>"Hello"</nms:name>
            </nms:domainValue>
        </nms:type>
    </nms:nmsObject>
</nms:nmsDocument>

需要解析该XML获取<nms:name>标签的值"Hello",编写了以下Kotlin数据类:

NmsDocument类

@JacksonXmlRootElement(localName = "nmsDocument", namespace = "nms")
@JsonIgnoreProperties(ignoreUnknown = true)
data class NmsDocument(
    @JacksonXmlProperty(localName = "nmsObject", namespace = "nms")
    val nmsObject: NmsObject
)

NmsObject类

@JsonIgnoreProperties(ignoreUnknown = true)
data class NmsObject(
    @JacksonXmlProperty(localName = "type", namespace = "nms", isAttribute = false)
    val type: Type
)

Type类

@JsonIgnoreProperties(ignoreUnknown = true)
data class Type(
    @JacksonXmlProperty(localName = "domainValue", namespace = "nms")
    val domainValue: DomainValue
)

DomainValue类

@JsonIgnoreProperties(ignoreUnknown = true)
data class DomainValue(
    @JacksonXmlProperty(localName = "name", namespace = "nms")
    val name: String
)

运行时出现错误:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.example.demo.Type (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('nms:Test')
at [Source: (StringReader); line: 3, column: 5] (through reference chain: com.example.demo.NmsDocument["nmsObject"]->com.example.demo.NmsObject["type"])

问题根源:Jackson默认会将xsi:type属性识别为多态类型标识,错误地把它映射到了NmsObject类的type字段,而非解析目标内部的<nms:type>标签。


解决方案

方案一:显式忽略xsi:type属性

修改NmsObject类,显式声明并忽略xsi:type属性,确保type字段正确映射到内部标签:

@JsonIgnoreProperties(ignoreUnknown = true)
data class NmsObject(
    @JacksonXmlProperty(localName = "type", namespace = "nms")
    val type: Type,
    // 声明xsi:type属性并标记为忽略
    @JacksonXmlProperty(localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
    @JsonIgnore
    val xsiType: String? = null
)

方案二:全局禁用xsi:type自动识别

在创建XmlMapper实例时,配置禁用USE_XSI_TYPE特性,这样Jackson就不会将xsi:type视为多态标识,结合@JsonIgnoreProperties(ignoreUnknown = true)会自动忽略该属性:

val xmlMapper = XmlMapper.builder()
    .disable(MapperFeature.USE_XSI_TYPE)
    .build()

验证

使用上述任一方案修改后,重新解析XML即可正常获取<nms:name>标签的值"Hello"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:43:13