用于kotlin中此XML响应的POJO对象

时间:2017-11-05 14:32:50

标签: java xml jackson kotlin

我正在使用返回XML的API:

<xyz-objects version="1.0">
    <object pk="1" model="roll">
        <field type="BigIntegerField" name="roll_number">1000000714</field>
        <field type="CharField" name="status">DL</field>
        <field name="scans">
            <object pk="1" model="scan_stages">
                <field type="DateTimeField" name="updated_on">11 Jul, 2017, 17:40</field>
            </object>
        </field>        
    </object>
</xyz-objects>

我使用的是杰克逊的XML映射器。

我尝试为此编写POJO对象,但这不起作用。

如何处理类型和名称等元素的属性? 你能举例说明吗?

2 个答案:

答案 0 :(得分:2)

由于您没有提供架构,因此很难猜测模型的某些部分。特别是,很难猜测field模型。所以我将它反序列化为一个JsonNode动态对象,它可以处理所有内容。 JsonIgnoreProperties以防你有一些额外的字段,这里没有提到。

首先,创建一些数据类:

@XmlRootElement(name = "xyz-objects")
@JsonIgnoreProperties(ignoreUnknown = true)
data class XyzObjects(
        @JacksonXmlProperty(isAttribute = true)
        val version: String,

        @JsonProperty(value = "object")
        @JacksonXmlElementWrapper(useWrapping = false)
        val objects: List<Object>
)

@XmlRootElement(name = "object")
@JsonIgnoreProperties(ignoreUnknown = true)
data class Object(
        @JacksonXmlProperty(isAttribute = true)
        val pk: String,

        @JacksonXmlProperty(isAttribute = true)
        val model: String,

        @JsonProperty(value = "field")
        @JacksonXmlElementWrapper(useWrapping = false)
        val fields: List<JsonNode>
)

回答您的问题:您可以使用JacksonXmlPropertyisAttribute属性来处理属性问题。列表可以使用JacksonXmlElementWrapper + JsonProperty进行处理(不要被名称欺骗,它用于处理名称中的复数形式,从而使它们在XML中也更具人性可读性。)

为了能够处理数据类,您需要使用registerKotlinModule注册Kotlin module

val text = """<xyz-objects version="1.0">
<object pk="1" model="roll">
    <field type="BigIntegerField" name="roll_number">1000000714</field>
    <field type="CharField" name="status">DL</field>
    <field name="scans">
        <object pk="1" model="scan_stages">
            <field type="DateTimeField" name="updated_on">11 Jul, 2017, 17:40</field>
        </object>
    </field>
</object>
</xyz-objects>"""
val mapper = XmlMapper().registerKotlinModule()
val node = mapper.readValue<XyzObjects>(text)

println(node)

它将打印:

XyzObjects(version=1.0, objects=[Object(pk=1, model=roll, fields=[{"type":"BigIntegerField","name":"roll_number","":"1000000714"}, {"type":"CharField","name":"status","":"DL"}, {"name":"scans","object":{"pk":"1","model":"scan_stages","field":{"type":"DateTimeField","name":"updated_on","":"11 Jul, 2017, 17:40"}}}])])

答案 1 :(得分:1)

根据我在https://github.com/FasterXML/jackson-module-kotlin/issues/138中所做的调查,这是一种解决方法,其类型比JsonNode workaround by madhead

data class Field(
    @JacksonXmlProperty(isAttribute = true)
    val type: String,

    @JacksonXmlProperty(isAttribute = true)
    val name: String,
) {
    @JacksonXmlText
    lateinit var value: String private set
}