我正在使用一个API,该API返回如下所示的XML:

<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>

我正在使用Jackson的XML映射器。

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

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

最佳答案

由于您未提供架构,因此很难猜测模型的某些部分。特别是,很难猜测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>
)

回答您的问题:您可以通过使用 isAttribute JacksonXmlProperty属性来处理属性。列表可以用 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"}}}])])

07-24 22:23