首页 > 解决方案 > JAXB 使用命名空间检索内部元素(返回空白)

问题描述

我想解组

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

data class Item(val author:String)

如果可能,直接读author/nameauthor字段。 如果不可能以干净/简单的方式,我想Author用字段创建类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>

所有模型类:

@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 = "")
}

标签: javaxml-parsingjaxbrss

解决方案


1)错误是@field:XmlElement而不是@XmlElement

这是 kotlin 属性/字段区分错误。

@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类并data class Item(val author:String)改用


推荐阅读