I have xml like this:
<horo>
<aries>
<today>
Сегодня вас могут здорово огорчить. Если от расстройства все начнет валится из рук, просто спокойно сядьте и тихонько подождите хорошей новости.
</today>
</aries>
<taurus>
<today>
Сегодня у вас могут возникнуть проблемы на личном фронте. Спасти вас от перспективы оказаться не у дел может сухой, рациональный и в высшей степени объективный подход к проблеме.
</today>
</taurus>
</horo>
And now i learning kotlin whith retrofit. I include libraries for parse xml, and not i cant understand how create object for parsing this xml. I have object:
@Root(name = "horo", strict = false)
open class DailyHoroscope{
@get : Element(name = "aries") var aries : Aries? = null
}
@Root(name = "aries", strict = false)
open class Aries{
@get : Element(name = "today") var today : String? = null
}
but i have error:
rg.simpleframework.xml.core.ConstructorException: Default constructor can not accept read only @org.simpleframework.xml.Element(data=false, name=aries, required=true, type=void) on method 'aries' in class ac.kotlintest.model.
upd
i writed code in java:
@Root(name = "horo", strict = false)
public class DailyHoroscopeJ {
@Element(name = "aries")
public Aries aries;
public Aries getAries() {
return aries;
}
public void setAries(Aries aries) {
this.aries = aries;
}
}
@Root(name = "aries", strict = false)
class Aries{
@Element(name = "today")
public String today;
public String getToday() {
return today;
}
public void setToday(String today) {
this.today = today;
}
}
and it work fine, then i convert to kotlin
@Root(name = "horo", strict = false)
class DailyHoroscope {
@get:Element(name = "aries")
var aries:Aries? = null
}
@Root(name = "aries", strict = false) class Aries {
@get:Element(name = "today")
var today:String? = null
}
but i have same problem((((
Android DOM(Document Object Model) parser is a program that parses an XML document and extracts the required information from it. This parser uses an object-based approach for creating and parsing the XML files. In General, a DOM parser loads the XML file into the Android memory to parse the XML document.
Android provides three types of XML parsers which are DOM,SAX and XMLPullParser. Among all of them android recommend XMLPullParser because it is efficient and easy to use.
The parser reads an XML document from the beginning to the end. When it encounters a node in the document, it generates an event that triggers the corresponding event handler for that node. The handler thus applies the application logic to process the node specifically.
XML document is commonly used to share the data on the internet. The data provided in XML format are able to update frequently and parsing them is a common task for network-based apps. In android, there are three types of XML parsers to parse the XML data and read them in android applications.
The answer of @daementus is almost perfect. If you want to use constructor injection with default parameters, you have to force Kotlin to generate constructor overloads:
data class Section @JvmOverloads constructor(
@field:Element(name = "id")
@param:Element(name = "id")
val id: Long,
@field:Attribute(name = "title", required = false)
@param:Attribute(name = "title", required = false)
val title: String = ""
)
Without it you will get Constructor not matched for class Section. By default Kotlin generates a constructor with all parameters and a special constructor.
Note: I would prefer to answer in the comments but I don't have enough points.
Indeed, Simple XML Framework has a few problems with Kotlin attributes and it can be a little tricky to get things to work.
To be honest, I am not quite sure what is the problem in your specific case, but I'd guess that the annotation shouldn't be specified for the getter, but rather for the field.
Anyway, I am combining Simple XML and Kotlin data classes this way, and it seems to be working fine :)
data class Section (
@field:Element(name = "id", required = false)
@param:Element(name = "id", required = false)
val id: Long? = null,
@field:Attribute(name = "title", required = false)
@param:Attribute(name = "title", required = false)
val title: String? = null
)
Edit: If you don't want to use data classes (which I highly recommend, but you might have a reason), this should work without the "data" keyword just fine. If you don't wish to create a constructor, just move the attribute declarations directly into the class and get rid of the @param annotation (the @field must stay).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With