JAXB 检索具有命名空间的内部元素(returns 空白)

JAXB retrieve inner element with namespace (returns blank)

我要解组

<item>
    <a10:author>
        <a10:name>AuthorName</a10:name>
    </a10:author>
</item>

data class Item(val author:String)

如果可能,直接将 author/name 读入 author 字段。 如果 clean/simple 方式 不可行,我想创建 Author class 和 name 字段,如下所示。 在下面的代码中,author.name 是空的,但它不应该是空的。为什么是空的?

样本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>

所有型号 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) 错误是 @field:XmlElement 而不是 @XmlElement

这是kotlin property/field区分错误。

来自

@XmlAccessorType(XmlAccessType.FIELD)
data class Author(@XmlElement(namespace = "http://www.w3.org/2005/Atom")
                  val name: String)

@XmlAccessorType(XmlAccessType.FIELD)
data class Author(@field:XmlElement(namespace = "http://www.w3.org/2005/Atom")
                  val name: String)

2) 另一种使用 @XmlAnyElement 的解决方案(额外的复杂性)

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,...)

但我仍然不知道是否可以删除 Author class 并改用 data class Item(val author:String)