I want to unmarshal
<item>
<a10:author>
<a10:name>AuthorName</a10:name>
</a10:author>
</item>
to
data class Item(val author:String)
if possible, by reading author/name
into author
field directly.
If not possible in clean/simple way, i want to create Author
class with name
field, as below. In below code, author.name
is empty, but it should not be. Why is it empty?
Sample XML
<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
<channel xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<title>SomeTitle</title>
<link>https://google.com</link>
<description>SomeDescription</description>
<os:totalResults>49</os:totalResults>
<item>
<link>https://google.com</link>
<a10:author>
<a10:name>AuthorName</a10:name>
</a10:author>
<title>SomeTitle</title>
<description>SomeDesc</description>
<pubDate>Fri, 06 Nov 2020 07:59:27 Z</pubDate>
</item>
</channel>
</rss>
All model classes:
@XmlRootElement(name = "rss", namespace = "http://www.w3.org/2005/Atom")
@XmlAccessorType(XmlAccessType.FIELD)
data class Rss(val channel: RssChannel?) {
constructor() : this(channel = null)
}
@XmlRootElement(name = "channel", namespace = "http://a9.com/-/spec/opensearch/1.1/")
@XmlAccessorType(XmlAccessType.FIELD)
data class RssChannel (val link: String,
val title: String,
val description: String,
@field:XmlElement(namespace = "http://a9.com/-/spec/opensearch/1.1/")
val totalResults: Int,
@field:XmlElement(name = "item")
val items: List<Item>?) {
constructor() : this(link = "", title = "", description = "", totalResults = 0, items = null)
}
@XmlAccessorType(XmlAccessType.FIELD)
data class Item( val title: String,
val description: String,
val link: String,
@field:XmlElement(namespace = "http://www.w3.org/2005/Atom")
val author: Author,
val pubDate: String) {
constructor() : this(title = "", description = "", link = "", author = Author(), pubDate = "")
}
@XmlAccessorType(XmlAccessType.FIELD)
data class Author(@XmlElement(namespace = "http://www.w3.org/2005/Atom")
val name: String) {
constructor() : this(name = "")
}
1) Error was @field:XmlElement
instead of @XmlElement
This is kotlin property/field distinction error.
From
@XmlAccessorType(XmlAccessType.FIELD)
data class Author(@XmlElement(namespace = "http://www.w3.org/2005/Atom")
val name: String)
To
@XmlAccessorType(XmlAccessType.FIELD)
data class Author(@field:XmlElement(namespace = "http://www.w3.org/2005/Atom")
val name: String)
2) Another solution using @XmlAnyElement
(extra complexity)
data class Author(@field:XmlAnyElement(lax = true)
val elements: MutableList<JAXBElement<String>>)
...
@XmlRegistry
class NameStringFactory {
@XmlElementDecl(name = "name", namespace = "http://www.w3.org/2005/Atom")
fun createName(name: String): JAXBElement<String> {
return JAXBElement<String>(QName("name"), String::class.java, name)
}
}
...
val jaxbContext = JAXBContext.newInstance(NameStringFactory::class.java,...)
But i still don't know if removing Author
class and using data class Item(val author:String)
instead is possible