I'm traying to parse XML with Retrofit2 and SimpleXmlConverterFactory, that's working until I tried to read attributes of a node, there, it crashes with no log.
My XML :
<HotelSearchRES>
<Destination id="1">Tunisie</Destination>
<City id="104">Hammamet</City>
<Currency>1</Currency>
<Language>1</Language>
<FromDate>01/12/2021</FromDate>
<ToDate>02/12/2021</ToDate>
</HotelSearchRES>
My Classes :
@Root(name = "HotelSearchRES", strict = false)
class SearchResultsWrapper @JvmOverloads constructor() {
@Element(name = "Destination")
var destination: Destination? = null
@set:Element(name = "City")
@get:Element(name = "City")
var city: String? = null
@set: Element(name = "Currency")
@get: Element(name = "Currency")
var currency: Int? = null
@set: Element(name = "Language")
@get: Element(name = "Language")
var language: Int? = null
@set: Element(name = "FromDate")
@get: Element(name = "FromDate")
var fromDate: String? = null
@set: Element(name = "ToDate")
@get: Element(name = "ToDate")
var toDate: String? = null
}
class Destination(){
@Attribute(required = false)
val id: String? = null
@Text(required = false)
val destination: String? = null
}
The problem seams related to attribute reading, so if I remove the first line everything works :
@Element(name = "Destination")
var destination: Destination? = null
Any help would be appreciated ;)
CodePudding user response:
In Kotlin, a field is only used as a part of a property to hold its value in memory. Fields cannot be declared directly. However, when a property needs a backing field, Kotlin provides it automatically. This backing field can be referenced in the accessors using the field
identifier
Do something like:
@field:Element(name = "Destination")
var destination: Destination? = null
By the way you don't need to do the @get
, @set
on your properties, you can use the @field
See this or here Annotations for detailed answers
CodePudding user response:
Ok, for those who are messing with parsing attributes, here are the correct class annotations :
@Root(name = "HotelSearchRES", strict = false)
class HotelSearchRES @JvmOverloads constructor(){
@field:Element(name = "Destination") var destination: Destination? = null
@field:Element(name = "City") var city: City? = null
@field:Element(name = "Currency") var currency: Int = 0
@field:Element(name = "Language") var language: Int = 0
@field:Element(name = "FromDate") var fromDate: String? = null
@field:Element(name = "ToDate") var toDate: String? = null
}
@Root(name = "Destination", strict = false)
class Destination {
@field:Attribute(name = "id", required = false) var id: Int = 0
@field:Text var text: String? = null
}
@Root(name = "City", strict = false)
class City {
@field:Attribute(name = "id", required = false) var id: Int = 0
@field:Text var text: String? = null
}
Thank you @MG1616 for the trick