androidjsonxmlkotlinsimple-framework

Android - Parse XML to JSON


My use case require me to fetch an XML formatted as below and need to map it into a JSON object:

<settings>
<client ip="......" lat="...." lon="...." isp="...." country="...."/>
<translation lang="xml"> </translation>
</settings>

I'm using Retrofit with Moshi as converter factory for the requests:

       Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create(moshi).asLenient())
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .build()

I tried to create the response model with the help of SimpleXml (com.squareup.retrofit2:converter-simplexml:2.9.0), but so far no luck. I keep getting this error:

com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was STRING at path $

Anyone might have an idea how to map this structure to Json? Thank you in advance!

Response models:

@Root(name = "settings", strict = false)
data class ConfigurationEntity(

    @field:Attribute(name = "client", required = false)
    @param:Attribute(name = "client", required = false)
    val client: ClientEntity?
)
@Root(name = "client")
data class ClientEntity(

    @field:Attribute(name = "ip", required = false)
    @param:Attribute(name = "ip", required = false)
    val ip: String?,

    @field:Attribute(name = "lat", required = false)
    @param:Attribute(name = "lat", required = false)
    val lat: String?,

    @field:Attribute(name = "lon", required = false)
    @param:Attribute(name = "lon", required = false)
    val lon: String?,

    @field:Attribute(name = "isp", required = false)
    @param:Attribute(name = "isp", required = false)
    val isp: String?,

    @field:Attribute(name = "country", required = false)
    @param:Attribute(name = "country", required = false)
    val country: String?
)

Solution

Retrofit builder:

       Retrofit.Builder()
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .build()

Models:

@Root(name = "settings", strict = false)
class ConfigurationEntity {

    @field:Element(required = false)
    lateinit var client: ClientEntity
}
@Root(name = "client", strict = false)
class ClientEntity {

    @field:Attribute
    lateinit var ip: String

    @field:Attribute
    lateinit var lat: String

    @field:Attribute
    lateinit var lon: String

    @field:Attribute
    lateinit var isp: String

    @field:Attribute
    lateinit var country: String
}

Also this link may be helpful Kotlin - parsing Xml response with list using SimpleXml


Solution

  • You will need to add this converter factory to your Retrofit Builder -

    Retrofit.Builder()
    .addConverterFactory(SimpleXmlConverterFactory.create())
    

    This allows Retrofit to interpret the XML that it is fetching to be converted to it's equivalent JSON Data Object.