XML Jackson 在 Kotlin 中与一个未真正嵌套的 XML 绑定
XML Jackson binding with a not really nested XML in Kotlin
我“长得不好看”XML。 (是的,它是有效的,但与我通常得到的以及我知道如何处理的不同)
通常我想要这样的东西:
<Parent....>
<Books>
<Book ...>
<Book ...>
<Book ...>
</Books>
</Parent>
abvoe XML 的我的数据 Class 将如下所示:
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,作为 GitHub Gist 的 Kotlin 脚本。它还在底部显示了反序列化 XML 的输出。
我“长得不好看”XML。 (是的,它是有效的,但与我通常得到的以及我知道如何处理的不同)
通常我想要这样的东西:
<Parent....>
<Books>
<Book ...>
<Book ...>
<Book ...>
</Books>
</Parent>
abvoe XML 的我的数据 Class 将如下所示:
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,作为 GitHub Gist 的 Kotlin 脚本。它还在底部显示了反序列化 XML 的输出。