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
相关产品推荐
相关产品推荐

