Kotlin - 使用 Jackson XmlMapper 反序列化
Kotlin - Deserializing with Jackson XmlMapper
我在使用 Jackson XML Mapper 正确解析 XML 文件时遇到了一些问题。
假设我有这个简单的 XML:
<Test>
<Simple>
<x>I am x</x>
<y>I am y</y>
</Simple>
</Test>
和这个简单的 class:
@Root(name="Simple",strict = false)
class Simple {
@Element(name = "x", required = false)
lateinit var x :String
@Element(name = "y", required = false)
lateinit var y :String
}
编译器不断抛出此错误:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Simple" (class Simple), not marked as ignorable (2 known properties: "x", "y"])
我猜是因为 Kotlin 无法在 class 中找到文件的正确结构?
问题是我需要解析一个更大的 xml 文件,并且需要避免镜像 xml 的每个元素,否则它会变得很大。
那么如何“部分”解析 xml,将根设置为 <Simple>
标签,避免 <Test>
标签?
非常感谢!
这是一个可行的解决方案。请注意,我已使映射器不区分大小写,以应对 XML 中大写的 Simple 属性。您可以使用 属性 上的注释来覆盖默认的小写名称。另请注意使用数据 类 消除任何需要使用 lateinit vars 或类似的东西:
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.MapperFeature
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
import com.fasterxml.jackson.dataformat.xml.XmlMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
data class Simple(val x: String, val y: String)
data class Test(val simple: Simple)
fun main() {
val xmlDeserializer = XmlMapper(JacksonXmlModule().apply {
setDefaultUseWrapper(false)
}).registerKotlinModule()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
val simple = Simple("x","y")
val test = Test(simple)
println(xmlDeserializer.writeValueAsString(test))
val stringToParse = "<Test><Simple><x>1</x><y>2</y></Simple></Test>"
val finalObject = xmlDeserializer.readValue(stringToParse, Test::class.java)
println(finalObject.simple.x)
}
确保您的 build.gradle.kts 具有这些依赖项(如果它们不存在的话):
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.1")
我在使用 Jackson XML Mapper 正确解析 XML 文件时遇到了一些问题。 假设我有这个简单的 XML:
<Test>
<Simple>
<x>I am x</x>
<y>I am y</y>
</Simple>
</Test>
和这个简单的 class:
@Root(name="Simple",strict = false)
class Simple {
@Element(name = "x", required = false)
lateinit var x :String
@Element(name = "y", required = false)
lateinit var y :String
}
编译器不断抛出此错误:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Simple" (class Simple), not marked as ignorable (2 known properties: "x", "y"])
我猜是因为 Kotlin 无法在 class 中找到文件的正确结构? 问题是我需要解析一个更大的 xml 文件,并且需要避免镜像 xml 的每个元素,否则它会变得很大。
那么如何“部分”解析 xml,将根设置为 <Simple>
标签,避免 <Test>
标签?
非常感谢!
这是一个可行的解决方案。请注意,我已使映射器不区分大小写,以应对 XML 中大写的 Simple 属性。您可以使用 属性 上的注释来覆盖默认的小写名称。另请注意使用数据 类 消除任何需要使用 lateinit vars 或类似的东西:
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.MapperFeature
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
import com.fasterxml.jackson.dataformat.xml.XmlMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
data class Simple(val x: String, val y: String)
data class Test(val simple: Simple)
fun main() {
val xmlDeserializer = XmlMapper(JacksonXmlModule().apply {
setDefaultUseWrapper(false)
}).registerKotlinModule()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
val simple = Simple("x","y")
val test = Test(simple)
println(xmlDeserializer.writeValueAsString(test))
val stringToParse = "<Test><Simple><x>1</x><y>2</y></Simple></Test>"
val finalObject = xmlDeserializer.readValue(stringToParse, Test::class.java)
println(finalObject.simple.x)
}
确保您的 build.gradle.kts 具有这些依赖项(如果它们不存在的话):
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.1")