【问题标题】:JAXB retrieve inner element with namespace (returns blank)JAXB 使用命名空间检索内部元素(返回空白)
【发布时间】:2020-11-15 13:02:24
【问题描述】:

我想解组

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

data class Item(val author:String)

如果可能,直接将author/name 读入author 字段。 如果不可能以干净/简单的方式,我想用name 字段创建Author 类,如下所示。 在下面的代码中,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 = "")
}

【问题讨论】:

  • 您的示例 XML 包含没有前缀的元素,但没有空前缀的命名空间。
  • 是的,有效
  • 所以 rss 元素中没有命名空间,但是命名空间是为 Rss 类指定的。

标签: java xml-parsing jaxb rss


【解决方案1】:

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)

【讨论】:

    猜你喜欢
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多