Retrofit+SimpleXml解析XML报Unparseable date: "1.8082"错误如何解决?
错误原因
- 核心错误:
Currency类中Rate字段类型定义错误:XML中标签存储的是浮点型汇率数值(如1.8081),但你将该字段声明为 Date类型,SimpleXml会尝试将数值字符串解析为日期,直接触发“无法解析日期”异常。 - 其他关联错误:
- 标签属性和子节点注解混用:
DailyExRates类中的Date是标签的属性,你错误使用了 @Element注解,应该用@Attribute注解。同时你将Date声明为Long类型,而XML中该属性值是格式为MM/dd/yyyy的字符串,直接解析会出现类型不匹配错误。Currency类中的Id是标签的属性,你也错误使用了 @Element注解,需要改为@Attribute。
DailyExRates的@Root注解中name值多了末尾空格:你写的是"DailyExRates ",和实际XML根标签名DailyExRates不一致,严格模式下会解析失败。Currency类中多余的text字段无对应XML节点,可直接删除。
- 标签属性和子节点注解混用:
解决方案
1. 修正POJO类定义
修正后的DailyExRates类
@Root(strict = false, name = "DailyExRates") // 去掉末尾多余空格 data class DailyExRates constructor( @field:ElementList(inline = true) var Currency: ArrayList<Currency>? = null, // 改为Attribute注解,先存为String后续自行转换日期,也可通过自定义Converter直接转成Date/Long类型 @field:Attribute(name = "Date", required = false) var Date: String? = null, )
修正后的Currency类
data class Currency constructor ( @field:Element(name = "NumCode", required = false) var NumCode: Int? = null, @field:Element(name = "CharCode", required = false) var CharCode: String? = null, @field:Element(name = "Scale", required = false) var Scale: Int? = null, @field:Element(name = "Name", required = false) var Name: String? = null, // 把Date类型改为Double,对应汇率数值 @field:Element(name = "Rate", required = false) var Rate: Double? = null, // 改为Attribute注解 @field:Attribute(name = "Id", required = false) var Id: Int? = null )
2. 可选:自动转换日期类型
如果需要直接将DailyExRates的Date字段解析为Date对象,可自定义SimpleXml转换器:
class DateConverter : Converter<Date> { private val format = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault()) override fun read(node: InputNode): Date { return format.parse(node.value) } override fun write(node: OutputNode, value: Date?) { node.value = value?.let { format.format(it) } } }
修改Date字段的注解配置:
@field:Attribute(name = "Date", required = false) @field:Convert(DateConverter::class) var Date: Date? = null
最后给SimpleXml序列化器开启注解策略,再配置到Retrofit中即可:
val strategy = AnnotationStrategy() val serializer = Persister(strategy) val retrofit = Retrofit.Builder() .addConverterFactory(SimpleXmlConverterFactory.create(serializer)) // 其余Retrofit配置 .build()
内容的提问来源于stack exchange,提问作者Mikhail
相关产品推荐
相关产品推荐

