问题描述
我有一个“不好看”的 XML。 (是的,它是有效的,但与我通常得到的以及我知道如何处理的不同)
通常我希望看到类似的内容:
<Parent....>
<Books>
<Book ...>
<Book ...>
<Book ...>
</Books>
</Parent>
我的 abvoe XML 数据类如下所示:
data class Parent(
@JacksonXmlProperty(localName = "Books")
@JacksonXmlElementWrapper
var books: List<Book>
)
data class Book(
.....
)
但不幸的是,我们传入的 XML 如下所示:
<Parent....>
<Book ...>
<Something>
<Book ....>
<Something>
<Book ...>
</parent>
所以我正在努力将它与普通的 Jackson Mapper 匹配,而不使用自定义的映射器。 (如果我需要定制一个,它应该是什么样子的?)
我的映射器如下所示:
val kotlinModule: KotlinModule = KotlinModule.Builder()
.strictnullchecks(false)
.nullIsSameAsDefault(true) // needed,else it will break for null https://github.com/FasterXML/jackson-module-kotlin/issues/130#issuecomment-546625625
.build()
val xmlMapper =
XmlMapper(JacksonXmlModule())
.registerModule(kotlinModule)
.registerModule(JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // to parse the dates as LocalDate,else parsing error
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)
.disable(DeserializationFeature.FAIL_ON_UNKNowN_PROPERTIES)
解决方法
要反序列化这样的 XML,您可以使用两个技巧:
- 明确关闭
List<Book>
的包装,因为他们直接坐在Parent
中 - 使用自定义 setter 解决引擎限制,这是 GitHub 问题 #275 中提出的解决方案
更具体地说,您可以对类进行注释以允许反序列化您的示例:
@JacksonXmlRootElement
class Parent {
@JacksonXmlProperty(localName = "Book")
@JacksonXmlElementWrapper(useWrapping = false)
var books: List<Book> = ArrayList()
set(value) {
field = books + value
}
}
data class Book(
@JacksonXmlProperty
val title: String
)
我上传了一个完整的示例,它使用您的 Jackson 配置和示例 XML,作为 Kotlin 脚本到 GitHub Gist。它还在底部显示了反序列化的 XML 的输出。