在 kotlin 中使用 SimpleXML 序列化改造 xml 响应
Serializing retrofit xml response with SimpleXML in kotlin
我正在尝试使用 SimpleXML 将改造 xml 响应序列化为一个对象。
但是出现以下异常:
org.simpleframework.xml.core.ValueRequiredException: Unable to satisfy @org.simpleframework.xml.ElementList(data=false, empty=true, entry=, inline=true, name=ALLFile, required=true, type=void) on field 'files''
响应示例:
<LIST>
<ALLFile>
<File>
<NAME>SOME FILE NAME</NAME>
<FPATH>SOME FILE PATH</FPATH>
<SIZE>160053622</SIZE>
<TIMECODE>1299673239</TIMECODE>
<TIME>2018/11/23 14:04:46</TIME>
<ATTR>33</ATTR>
</File>
</ALLFile>
<ALLFile>
<File>
<NAME>SOME FILE NAME</NAME>
<FPATH>SOME FILE PATH</FPATH>
<SIZE>160053622</SIZE>
<TIMECODE>1299673559</TIMECODE>
<TIME>2018/11/23 14:14:46</TIME>
<ATTR>33</ATTR>
</File>
</ALLFile>
</LIST>
对象:
@Root(name = "LIST", strict = false)
data class ListResponse @JvmOverloads constructor(
@field:ElementList(name = "ALLFile", inline = true) var files: List<GetVideosResponse>? = null
)
@Root(strict = false, name = "File")
data class GetVideosResponse @JvmOverloads constructor(
@field:Element(name = "NAME", required = false) var name: String? = null,
@field:Element(name = "FPATH", required = false) var fPath: String? = null,
@field:Element(name = "SIZE", required = false) var size: Int? = null,
@field:Element(name = "TIMECODE", required = false) var timeCode: Long? = null,
@field:Element(name = "TIME", required = false) var time: String? = null,
@field:Element(name = "ATTR", required = false) var attr: Int? = null)
我收到了来自服务器的 200 响应,因此可以排除我的请求逻辑的问题。这让我相信问题在于序列化对象,有什么想法吗?
找到了解决这个问题的方法,不一定是答案,但对我有用...
我将 XML 响应作为字符串,将其转换为 JSON 然后使用我常用的JSON 序列化库 (moshi) 将 JSON 序列化为一个对象。
private fun parseXmlToJsonObject(xml: String) : String {
var jsonObj: JSONObject? = null
try {
jsonObj = XML.toJSONObject(xml)
} catch (e: JSONException) {
Log.e("JSON exception", e.message)
e.printStackTrace()
}
return jsonObj.toString()
}
fun<T> parseResponse(xml: String, clazz: Class<T>) : T {
try {
return initializeMoshi().adapter(clazz).fromJson(parseXmlToJsonObject(xml))!!
}catch (e: IOException){
throw IllegalArgumentException("Could not deserialize: $xml into class: $clazz")
}
}
private fun initializeMoshi(): Moshi {
return Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
}
并这样称呼它:
val myObject = parseResponse(response.body()!!.string(), MyJsonClass::class.java)
我正在尝试使用 SimpleXML 将改造 xml 响应序列化为一个对象。
但是出现以下异常:
org.simpleframework.xml.core.ValueRequiredException: Unable to satisfy @org.simpleframework.xml.ElementList(data=false, empty=true, entry=, inline=true, name=ALLFile, required=true, type=void) on field 'files''
响应示例:
<LIST>
<ALLFile>
<File>
<NAME>SOME FILE NAME</NAME>
<FPATH>SOME FILE PATH</FPATH>
<SIZE>160053622</SIZE>
<TIMECODE>1299673239</TIMECODE>
<TIME>2018/11/23 14:04:46</TIME>
<ATTR>33</ATTR>
</File>
</ALLFile>
<ALLFile>
<File>
<NAME>SOME FILE NAME</NAME>
<FPATH>SOME FILE PATH</FPATH>
<SIZE>160053622</SIZE>
<TIMECODE>1299673559</TIMECODE>
<TIME>2018/11/23 14:14:46</TIME>
<ATTR>33</ATTR>
</File>
</ALLFile>
</LIST>
对象:
@Root(name = "LIST", strict = false)
data class ListResponse @JvmOverloads constructor(
@field:ElementList(name = "ALLFile", inline = true) var files: List<GetVideosResponse>? = null
)
@Root(strict = false, name = "File")
data class GetVideosResponse @JvmOverloads constructor(
@field:Element(name = "NAME", required = false) var name: String? = null,
@field:Element(name = "FPATH", required = false) var fPath: String? = null,
@field:Element(name = "SIZE", required = false) var size: Int? = null,
@field:Element(name = "TIMECODE", required = false) var timeCode: Long? = null,
@field:Element(name = "TIME", required = false) var time: String? = null,
@field:Element(name = "ATTR", required = false) var attr: Int? = null)
我收到了来自服务器的 200 响应,因此可以排除我的请求逻辑的问题。这让我相信问题在于序列化对象,有什么想法吗?
找到了解决这个问题的方法,不一定是答案,但对我有用...
我将 XML 响应作为字符串,将其转换为 JSON 然后使用我常用的JSON 序列化库 (moshi) 将 JSON 序列化为一个对象。
private fun parseXmlToJsonObject(xml: String) : String {
var jsonObj: JSONObject? = null
try {
jsonObj = XML.toJSONObject(xml)
} catch (e: JSONException) {
Log.e("JSON exception", e.message)
e.printStackTrace()
}
return jsonObj.toString()
}
fun<T> parseResponse(xml: String, clazz: Class<T>) : T {
try {
return initializeMoshi().adapter(clazz).fromJson(parseXmlToJsonObject(xml))!!
}catch (e: IOException){
throw IllegalArgumentException("Could not deserialize: $xml into class: $clazz")
}
}
private fun initializeMoshi(): Moshi {
return Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
}
并这样称呼它:
val myObject = parseResponse(response.body()!!.string(), MyJsonClass::class.java)