Kotlin 1.2.21 + SimpleXml 2.3.0 - 消费列表错误(必须标记set get方法)

Posted

技术标签:

【中文标题】Kotlin 1.2.21 + SimpleXml 2.3.0 - 消费列表错误(必须标记set get方法)【英文标题】:Kotlin 1.2.21 + SimpleXml 2.3.0 - consume List error (must mark set get method) 【发布时间】:2018-07-22 13:04:43 【问题描述】:

我正在尝试使用 Retrofit 2 的 SimpleXML 来使用 XML。在与 Kotlin 苦苦挣扎数小时后,我决定尝试 Java 版本,然后转换为 Kotlin。 Java版本运行良好......

错误:

java.lang.RuntimeException: org.simpleframework.xml.core.MethodException: Annotation @org.simpleframework.xml.ElementList(data=false, empty=true, entry=, inline=true, name=entry, required=true, type=void) must mark a set or get method

我需要一个能够使用该 XML 的 Kotlin 模型类。 这是输入:

<feed>
   <entry>
        <id> someid </id>
        <published> somedate </published>
   </entry>

   <entry>
        <id> someid2 </id>
        <published> somedate2 </published>
   </entry>
</feed>

Java 模型类版本(工作正常):

@Root(name = "feed", strict = false)
public class MFeed 
    @ElementList(name = "entry", inline = true)
    private List<MEntry> entriesList;

    public MFeed(List<MEntry> entriesList) 
        this.entriesList = entriesList;
    

    public MFeed() 
    

    public List<MEntry> getEntriesList() 
        return entriesList;
    

    public void setEntriesList(List<MEntry> entriesList) 
    this.entriesList = entriesList;
    


@Root(name = "entry", strict = false)
public class MEntry 

    @Element(name = "id")
    private String id;

    @Element(name = "published")
    private String published;

    public MEntry() 
    

    public MEntry(String id, String published) 
        this.id = id;
        this.published = published;
    

    public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    

    public String getPublished() 
        return published;
    

    public void setPublished(String published) 
        this.published = published;
    

自动生成的 Kotlin 模型如下所示:

@Root(name = "feed", strict = false)
class Feed 
    @ElementList(name = "entry", inline = true)
    private var entriesList: List<MEntry>? = null

    //autogenerated by converter java -> kotlin
    constructor(entriesList: List<MEntry>) 
        this.entriesList = entriesList
    

    //autogenerated by converter java -> kotlin
    constructor() 


@Root(name = "entry", strict = false)
class Entry 
    @Element(name = "id")
    var id: String? = null

    @Element(name = "published")
    var published: String? = null

    //autogenerated by converter java -> kotlin
    constructor() 

    //autogenerated by converter java -> kotlin
    constructor(id: String, published: String) 
        this.id = id
        this.published = published
    

我为消费 XML 列表提供了很多服务,包括 this 帖子、this 和 this。没有工作。也许它们已经过时了。有人遇到过这样的问题吗?

【问题讨论】:

【参考方案1】:

尝试将@field 添加到您的注释@Element*。您可以将属性移动到构造函数,也可以将data 修饰符添加到您的类中。像这样:

@Root(name = "feed", strict = false)
data class Feed(
        @field:ElementList(name = "entry", inline = true)
        var entriesList: List<Entry>? = null
)

@Root(name = "entry", strict = true)
data class Entry(
        @field:Element(name = "id")
        var id: String? = null,

        @field:Element(name = "published")
        var published: String? = null
)

有了这个我已经成功反序列化 xml:

import org.simpleframework.xml.Element
import org.simpleframework.xml.ElementList
import org.simpleframework.xml.Root
import org.simpleframework.xml.core.Persister

private val testXml = """
<feed>
   <entry>
        <id> someid </id>
        <published> somedate </published>
   </entry>

   <entry>
        <id> someid2 </id>
        <published> somedate2 </published>
   </entry>
</feed>
""".trimIndent()

@Root(name = "feed", strict = false)
data class Feed(
        @field:ElementList(name = "entry", inline = true)
        var entriesList: List<Entry>? = null
)

@Root(name = "entry", strict = true)
data class Entry(
        @field:Element(name = "id")
        var id: String? = null,

        @field:Element(name = "published")
        var published: String? = null
)

fun main(args: Array<String>) 
    println(testXml)

    val serializer = Persister()

    val example = serializer.read(Feed::class.java, testXml)

    println(example)

【讨论】:

哇,终于成功了!太感谢了。在 kotlin 项目中使用 java 吓到我了:D 我正在尝试做同样的事情,但总是在线程“main”java.lang.ClassNotFoundException 中得到相同的错误异常:com.vipera.data.serversoap.EnvelopeKt 和我的数据类 y Envelope.kt 数据类信封 (@field:Element(name = "soap-env:Body", required = false) param:Element(name = "soap-env:Body", required = false) var body: Body? = null)跨度>

以上是关于Kotlin 1.2.21 + SimpleXml 2.3.0 - 消费列表错误(必须标记set get方法)的主要内容,如果未能解决你的问题,请参考以下文章

PHP 5 SimpleXML 函数

PHP 5 SimpleXML 函数

雷林鹏分享:PHP SimpleXML

simplexml_load_file 和 simplexml_load_string 之间的区别

SimpleXML 属性到数组

使用 SimpleXML 读取 RSS 提要