Search code examples
androidretrofitretrofit2

How to parse xml response using retrofit in kotlin?


I have the following response:

<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok">
    <photos page="1" pages="3704" perpage="100" total="370320">
        <photo id="49658592343" owner="138998919@N06" secret="0db4e03977" server="65535" farm="66" title="mmm " ispublic="1" isfriend="0" isfamily="0" />
        <photo id="49658586758" owner="156045424@N06" secret="2444dda679" server="65535" farm="66" title="Boeing 787-9 (G-CKOG) Norwegian Airlines" ispublic="1" isfriend="0" isfamily="0" />
        <photo id="49659129251" owner="156045424@N06" secret="97d1bd202e" server="65535" farm="66" title="Boeing 787-9 (G-CKOG) Norwegian Airlines" ispublic="1" isfriend="0" isfamily="0" />
         </photos>
</rsp>

and I am using SimpleXmlConverterFactory as a retrofit converter .I have converted the above response to json through an online converter and created a data class from it, parent class is as follows:

data class ResponseImages(
    val photos: Photos,
    val stat: String
)

but I am getting this error everytime i run the app:

org.simpleframework.xml.core.AttributeException: Attribute 'stat' does not have a match in class com.abx.cbz.Response.ResponseImages at line -1

so what I am doing wrong here?


Solution

  • By reading various SO threads i have managed to make it work by using the following code block:

    @Root(name = "photos")
    data class Photos @JvmOverloads constructor(
    
        @field:Attribute(name = "page")
        @param:Attribute(name = "page")
        var page: String,
    
        @field:Attribute(name = "pages")
        @param:Attribute(name = "pages")
        var pages: String,
    
        @field:Attribute(name = "perpage")
        @param:Attribute(name = "perpage")
        var perpage: String,
    
        @field:ElementList(name = "photo", inline = true)
        @param:ElementList(name = "photo", inline = true)
        var photo: List<Photo>,
    
        @field:Attribute(name = "total")
        @param:Attribute(name = "total")
        var total: String
    )
    

    The same format should be used for other data classes too, I am only displaying one. There needs to be an empty constructor that's why I have used @JvmOverloads but the use of @param annotation is not that clear yet, a brief idea is we have to force Kotlin to generate constructor overloads.