无法通过Retrofit将XML响应解析为Kotlin数据类
解决Retrofit+SimpleXML解析XML列表的ElementException错误
问题场景
调用返回XML格式的REST API,使用Retrofit搭配SimpleXML Converter Factory解析为Kotlin数据类时,出现以下错误:
org.simpleframework.xml.core.ElementException: Element 'result[1]/author[1]' does not have a match in class BookList
API返回的XML响应:
<category> <api-version>1.0</api-version> <books> <list> <result> <author>Hello1</author> <brief>Hii</brief> </result> <result> <author>Hello2</author> <brief>Hii2</brief> </result> </list> </books> </category>
原Kotlin数据类定义:
data class CategoryResponseModel( @field:Element(name = "api-version", required = false) @param:Element(name = "api-version", required = false) val apiVersion: String? = null, @field:Element(name = "books", required = false) @param:Element(name = "books", required = false) val books: Books? = null ) data class Books( @field:Element(name = "list", required = false) @param:Element(name = "list", required = false) val list: BookList? = null ) @Root(name = "list") data class BookList( @field:Element(name = "result", required = false) @param:Element(name = "result", required = false) val result: List<BookSearchResult>? = null, ) data class BookSearchResult( @field:Element(name = "author", required = false) @param:Element(name = "author", required = false) val author: String? = null, @field:Element(name = "brief", required = false) @param:Element(name = "brief", required = false) val briefSynopsis: String? = null, )
错误原因
SimpleXML解析列表类型时,必须使用@ElementList注解标记,而非普通的@Element。原代码中BookList类用@Element标记List<BookSearchResult>,导致解析器无法识别多个<result>元素是列表项,进而抛出匹配错误。
修正方案
修改BookList类的注解为@ElementList,并添加inline = true参数(因为<result>元素直接嵌套在<list>下,没有额外的列表包裹元素)。同时简化Kotlin数据类的注解写法,无需同时标注@field:和@param:。
修正后的完整数据类:
data class CategoryResponseModel( @field:Element(name = "api-version", required = false) val apiVersion: String? = null, @field:Element(name = "books", required = false) val books: Books? = null ) data class Books( @field:Element(name = "list", required = false) val list: BookList? = null ) @Root(name = "list") data class BookList( @field:ElementList(name = "result", inline = true, required = false) val result: List<BookSearchResult>? = null ) data class BookSearchResult( @field:Element(name = "author", required = false) val author: String? = null, @field:Element(name = "brief", required = false) val briefSynopsis: String? = null )
关键说明
@ElementList:专门用于标记XML中的重复元素列表inline = true:当列表元素直接作为父元素的子节点(而非被单独的列表容器包裹)时必须添加该参数- Kotlin中只需标注
@field:注解即可,无需重复标注@param:,简化代码结构
内容的提问来源于stack exchange,提问作者Purvesh Dodiya
相关产品推荐
相关产品推荐

