解析 RSS Feed 时出现运行时异常

问题描述 投票:0回答:1

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(),但它们不适用于我的情况。

谢谢

android xml-parsing runtime-error
1个回答
0
投票

经过两天的更改终于成功改变了我的响应模型,现在它工作正常。

新闻提要响应模型

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? = ""

  1. inline = true
    您指定要解析的元素位于目标元素的同一父树中 - 它们不是嵌套的子元素。

  2. @set:Path("title")
    :序列化此类对象时与 title 属性对应的 XML 元素的路径。 @set:前缀表示该注解应用于属性的setter方法。

  3. @set:Text(required = false)
    :title 属性可以包含文本内容,并且反序列化时 XML 元素不需要具有此属性。

https://github.com/ngallagher/simplexml/issues/35

https://github.com/novoda/simple-easy-xml-parser/tree/master

© www.soinside.com 2019 - 2024. All rights reserved.