Jackson XmlMapper forces lower case tag names while writing XML to a file

Viewed 736

I have a problem while trying to use XmlMapper to write XML file from POJO. XmlMapper forces lower case tag names even though I am using JacksonXmlProperty(localname ="UPPERCASE")

Here is my code for my mapped POJOS

ItemXML:

data class ItemXML(
    @JacksonXmlProperty(localName = "ITEMTYPE") val itemType: String,
    @JacksonXmlProperty(localName = "ITEMID") val itemId: String,
    @JacksonXmlProperty(localName = "QTY") val qty: Int,
    @JacksonXmlProperty(localName = "COLOR") val color: Int,
    @JacksonXmlProperty(localName = "EXTRA") val extra: String,
    @JacksonXmlProperty(localName = "ALTERNATE") val alternate: String,
    @JacksonXmlProperty(localName = "MATCHID") val matchId: Int,
    @JacksonXmlProperty(localName = "COUNTERPART") val counterpart: String
)

InventoryXML

@JacksonXmlRootElement(localName = "INVENTORY")
data class InventoryXML(
    @JacksonXmlProperty(localName = "ITEM")
    @JacksonXmlElementWrapper(useWrapping = false)
    val item: List<ItemXML>
)

Here is the code for writing XML to a file placed in OnCreate() method:

inventoryXml = xmlMapper.readValue(data, InventoryXML::class.java)

pathFile = filesDir.absolutePath + "/inventory.xml"

xmlMapper.writeValue(File(pathFile), inventoryXml)

And here is the file that has been saved (As you can see only INVENTORY tag has been saved in Upper Case)

<INVENTORY>
  <item>
    <alternate>N</alternate>
    <color>0</color>
    <counterpart>N</counterpart>
    <extra>N</extra>
    <itemid>old012</itemid>
    <itemtype>M</itemtype>
    <matchid>0</matchid>
    <qty>1</qty>
  </item>
  <item>
    <alternate>N</alternate>
    <color>11</color>
    <counterpart>N</counterpart>
    <extra>N</extra>
    <itemid>3430c02</itemid>
    <itemtype>P</itemtype>
    <matchid>0</matchid>
    <qty>1</qty>
  </item>
</INVENTORY>

What is wrong with this code? I want the tags to be saved as specified in JacksonXmlProperty's localName attribute.

2 Answers

Rename the properties to follow standard Bean naming conventions, i.e. camel-case, since that is what Jackson expects:

ItemXML:

data class ItemXML(
    @JacksonXmlProperty(localName = "ITEMTYPE") val itemType: String,
    @JacksonXmlProperty(localName = "ITEMID") val itemId: String,
    @JacksonXmlProperty(localName = "QTY") val qty: Int,
    @JacksonXmlProperty(localName = "COLOR") val color: Int,
    @JacksonXmlProperty(localName = "EXTRA") val extra: String,
    @JacksonXmlProperty(localName = "ALTERNATE") val alternate: String,
    @JacksonXmlProperty(localName = "MATCHID") val matchId: Int,
    @JacksonXmlProperty(localName = "COUNTERPART") val counterpart: String
)

InventoryXML

@JacksonXmlRootElement(localName = "INVENTORY")
data class InventoryXML(
    @JacksonXmlProperty(localName = "ITEM")
    @JacksonXmlElementWrapper(useWrapping = false)
    val item: List<ItemXML>
)

You can set a PropertyNamingStrategy for your Jackson XmlMapper. There is no pre-defined class or constant for all upper case naming, but it's easy to create your own:

class UpperCaseStrategy : PropertyNamingStrategyBase() {
    override fun translate(input: String): String =
        input.toUpperCase()
}

val xmlMapper = XmlMapper().apply {
    setPropertyNamingStrategy(UpperCaseStrategy())
}
Related