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

Android Retrofit解析XML遇冲突:title标签重复致解析异常

解决Retrofit+SimpleXML解析含重复标签XML的异常问题

问题背景

使用Retrofit 2.9.0结合SimpleXML转换器解析第三方XML接口时,因<channel>和每个<item>标签下都存在<title>标签,抛出java.lang.RuntimeException: org.simpleframework.xml.core.PersistenceException异常。

依赖配置

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//retrofit XML
implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'

原数据类代码

@Root(name = "rss", strict = false)
class RSSFeed @JvmOverloads constructor(
    @field: Element(name = "channel") var channel: PodcastChannel? = null
)

@Root(name = "channel", strict = false)
class PodcastChannel @JvmOverloads constructor(
    @field: Element(name = "title", required = false) var title: String? = null,
    @field: ElementList(inline = true) var itemList: List<PodcastItem>? = null
)

@Root(name = "item", strict = false)
class PodcastItem @JvmOverloads constructor(
    @field: Element(name = "title", required = false) var title: String = "",
    @field: Element(name = "description", required = false) var description: String = "",
)

可行解决办法

1. 修正ElementList的注解配置

问题核心大概率是PodcastChannel中的ElementList未明确指定对应XML标签名,导致SimpleXML无法正确识别<item>列表。修改itemList字段的注解,补充name="item"参数:

@Root(name = "channel", strict = false)
class PodcastChannel @JvmOverloads constructor(
    @field:Element(name = "title", required = false) var title: String? = null,
    @field:ElementList(name = "item", inline = true, required = false) var itemList: List<PodcastItem>? = null
)

2. 调整Kotlin注解作用目标

Kotlin的@field:注解可能导致SimpleXML解析时的字段识别冲突,直接去掉@field:前缀,将注解作用在属性上:

@Root(name = "rss", strict = false)
class RSSFeed @JvmOverloads constructor(
    @Element(name = "channel") var channel: PodcastChannel? = null
)

@Root(name = "channel", strict = false)
class PodcastChannel @JvmOverloads constructor(
    @Element(name = "title", required = false) var title: String? = null,
    @ElementList(name = "item", inline = true, required = false) var itemList: List<PodcastItem>? = null
)

@Root(name = "item", strict = false)
class PodcastItem @JvmOverloads constructor(
    @Element(name = "title", required = false) var title: String = "",
    @Element(name = "description", required = false) var description: String = "",
)

3. 显式声明SimpleXML依赖版本

Retrofit的converter-simplexml依赖的SimpleXML版本可能存在兼容问题,在gradle中显式添加指定版本的SimpleXML依赖:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'
// 显式声明SimpleXML版本,解决潜在兼容冲突
implementation 'org.simpleframework:simple-xml:2.7.1'

4. 简化构造函数,避免@JvmOverloads干扰

去掉@JvmOverloads注解,手动实现无参和带参构造函数,确保SimpleXML能正确识别类的构造逻辑:

@Root(name = "rss", strict = false)
class RSSFeed {
    @Element(name = "channel")
    var channel: PodcastChannel? = null

    constructor()
    constructor(channel: PodcastChannel?) {
        this.channel = channel
    }
}

@Root(name = "channel", strict = false)
class PodcastChannel {
    @Element(name = "title", required = false)
    var title: String? = null

    @ElementList(name = "item", inline = true, required = false)
    var itemList: List<PodcastItem>? = null

    constructor()
    constructor(title: String?, itemList: List<PodcastItem>?) {
        this.title = title
        this.itemList = itemList
    }
}

@Root(name = "item", strict = false)
class PodcastItem {
    @Element(name = "title", required = false)
    var title: String = ""

    @Element(name = "description", required = false)
    var description: String = ""

    constructor()
    constructor(title: String, description: String) {
        this.title = title
        this.description = description
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:35:12