RSS 提要网址 - https://feeds.simplecast.com/qm_9xx0g
我的视图模型类功能
fun getXmlRequest(url: String): LiveData<List<NewsXmlCustomModel>> {
isLoading.postValue(true)
val liveData = MutableLiveData<List<NewsXmlCustomModel>>()
val coreAdXMLService = retrofitXML?.client?.create(CoreAdXmlService::class.java)
coreAdXMLService?.loadNewsResponse(url)?.enqueue(object : Callback<NewsFeedResponseModel> {
override fun onFailure(call: Call<NewsFeedResponseModel>, t: Throwable) {
isLoading.postValue(false)
liveData.postValue(emptyList())
}
override fun onResponse(call: Call<NewsFeedResponseModel>, response: Response<NewsFeedResponseModel>) {
val responseBody: NewsFeedResponseModel? = response.body()
responseBody?.channel?.item?.let {
val list = mutableListOf<NewsXmlCustomModel>()
it.forEachIndexed { index, it ->
val newsXmlCustomModel = NewsXmlCustomModel()
newsXmlCustomModel.type = ""
newsXmlCustomModel.title = it.title
newsXmlCustomModel.pos = (index % 2).toString()
newsXmlCustomModel.pubDate = it.pubDate
newsXmlCustomModel.link = it.link
newsXmlCustomModel.description = it.description
newsXmlCustomModel.descriptionLink = it.link
val xml = "<root>${it.description}</root>"
val doc: Document? =
try {
DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(InputSource(StringReader(xml)))
} catch (e: java.lang.Exception) {
logReport(e.message)
null
}
val errNodes: NodeList? = doc?.getElementsByTagName("root")
val node: Node? = errNodes?.item(0)
if (node != null) {
if (node.hasChildNodes()) {
val child: Node? = node.firstChild
val value: String? = child?.childNodes?.item(0)?.nodeValue?.let {
it.replace("<.*?>".toRegex(), "")
} ?: run {
it.description?.replace("<.*?>".toRegex(), "")
}
newsXmlCustomModel.desc = value
}
} else {
val pattern: Pattern = Pattern.compile("<p>(.+?)</p>", Pattern.CASE_INSENSITIVE)
val matcher: Matcher = pattern.matcher(it.description)
matcher.find()
newsXmlCustomModel.desc =
try {
matcher.group(1)
} catch (e: Exception) {
it.description?.replace("<.*?>".toRegex(), "") ?: ""
}
}
var imageUrl = ""
if (it.description?.contains("<img") == true) {
val str: List<String>? = it.description?.split("src=")?.getOrNull(1)?.split("\"")
imageUrl = str?.getOrNull(1) ?: ""
}
if (imageUrl == "") {
imageUrl = it.enclosure?.url ?: ""
}
newsXmlCustomModel.imageLink = imageUrl
newsXmlCustomModel.contentImg = imageUrl
list.add(newsXmlCustomModel)
}
isLoading.postValue(false)
liveData.postValue(list.toList())
} ?: run {
isLoading.postValue(false)
liveData.postValue(null)
}
}
})
return liveData
}
模型类
package com.my.appy
import androidx.annotation.Keep
import org.simpleframework.xml.Attribute
import org.simpleframework.xml.Element
import org.simpleframework.xml.ElementList
import org.simpleframework.xml.Root
import java.io.Serializable
@Root(name = "news", strict = false)
class NewsFeedResponseModel : Serializable {
@set:Element(name = "channel", required = false)
@get:Element(name = "channel", required = false)
var channel: NewsFeedChannel? = null
}
@Root(name = "channel", strict = false)
class NewsFeedChannel : Serializable {
@set:Element(name = "title", required = false)
@get:Element(name = "title", required = false)
var title: String? = ""
@set:ElementList(inline = true, name = "item", required = false)
@get:ElementList(inline = true, name = "item", required = false)
var item: ArrayList<NewsFeedItem>? = null
}
@Root(name = "item", strict = false)
class NewsFeedItem : Serializable {
@set:Element(name = "title", required = false)
@get:Element(name = "title", required = false)
var title: String? = ""
@set:Element(name = "description", required = false)
@get:Element(name = "description", required = false)
var description: String? = ""
@set:Element(name = "pubDate", required = false)
@get:Element(name = "pubDate", required = false)
var pubDate: String? = ""
@set:Element(name = "link", required = false)
@get:Element(name = "link", required = false)
var link: String? = ""
@set:Element(name = "image", required = false)
@get:Element(name = "image", required = false)
var image: NewsImageSourceAttribute? = null
@set:Element(name = "enclosure", required = false)
@get:Element(name = "enclosure", required = false)
var enclosure: NewsEnclosureImageSourceAttribute? = null
@set:Element(name = "media", required = false)
@get:Element(name = "media", required = false)
var media: String? = "123"
}
@Root(name = "description", strict = false)
class NewsImageSourceAttribute : Serializable {
@set:Attribute(name = "img", required = false)
@get:Attribute(name = "img", required = false)
var img: NewsImgSourceAttribute? = null
}
@Root(name = "enclosure", strict = false)
class NewsEnclosureImageSourceAttribute : Serializable {
@set:Attribute(name = "url", required = false)
@get:Attribute(name = "url", required = false)
var url: String? = ""
}
@Root(name = "img", strict = false)
class NewsImgSourceAttribute : Serializable {
@set:Attribute(name = "src", required = false)
@get:Attribute(name = "src", required = false)
var img: String? = ""
}
出现错误
java.lang.RuntimeException:org.simpleframework.xml.core.PersistenceException:元素“title”已与@org.simpleframework.xml.Element一起使用(data = false,name = title,required = false,type = void)在第 41 行的方法“title”上
尝试解析但出现运行时异常。我在堆栈溢出上尝试了不同的解决方案,例如如何解决 org.simpleframework.xml.core.ValueRequiredException:无法满足@org.simpleframework.xml.ElementList(),但它们不适用于我的情况。
谢谢
经过两天的更改终于成功改变了我的响应模型,现在它工作正常。
新闻提要响应模型
import org.simpleframework.xml.Path
import org.simpleframework.xml.Root
import org.simpleframework.xml.Text
import java.io.Serializable
@Keep
@Root(name = "news", strict = false)
class NewsFeedResponseModel : Serializable {
@set:Element(name = "channel", required = false)
@get:Element(name = "channel", required = false)
var channel: NewsFeedChannel? = null
}
@Keep
@Root(name = "channel", strict = false)
class NewsFeedChannel : Serializable {
@set:Element(name = "title", required = false)
@get:Element(name = "title", required = false)
var title: String? = ""
@set:ElementList(inline = true, name = "item", required = false)
@get:ElementList(inline = true, name = "item", required = false)
var item: ArrayList<NewsFeedItem>? = null
}
@Keep
@Root(name = "item", strict = false)
class NewsFeedItem : Serializable {
@set:Path("title")
@set:Text(required = false)
@get:Path("title")
@get:Text(required = false)
var title: String? = ""
inline = true
您指定要解析的元素位于目标元素的同一父树中 - 它们不是嵌套的子元素。
@set:Path("title")
:序列化此类对象时与 title 属性对应的 XML 元素的路径。 @set:前缀表示该注解应用于属性的setter方法。
@set:Text(required = false)
:title 属性可以包含文本内容,并且反序列化时 XML 元素不需要具有此属性。
https://github.com/ngallagher/simplexml/issues/35
https://github.com/novoda/simple-easy-xml-parser/tree/master