FasterXML / jackson-dataformat-xml

Extension for Jackson JSON processor that adds support for serializing POJOs as XML (and deserializing from XML) as an alternative to JSON

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

XmlMapper cannot correctly map Map

HenryYihengXu opened this issue · comments

I have an object with a map field and I want to map it to a XML file. However, the resulting XML file does not contains pairs like normal XML. Instead, it treat each key as a data type and each value as the value of that data type. For example, I have

class MyObject {
  private final Map<String, Integer> myMap;

  public MyObject() {
    myMap = new HashMap<>();
    myMap.put("a", 1);
    myMap.put("b", 2);

  // Getter
}

I get

<myMap>
  <a>1</a>
  <b>2</b>
</myMap>

But it is supposed to be

<myMap>
  <entry>
    <key>a</key>
    <value>1</value>
  </entry>
  <entry>
    <key>b</key>
    <value>2</value>
  </entry>
</myMap>

Do you know how to solve this issue?

What Jackson produces is what is intended (so it is a feature not bug). To get output you want (which has extra entry for some reason), you probably need a custom serializer. Or you need to convert Map into Java Object with structure that matches output that you want (List of Entry objects with 2 fields, key and value).

Okay I guess for very simple string key this intended thing is okay, but in my case, the key of my map is a string representing a path so it contains '/'. It will be written into <> and then cause parse error in deserialization. For example if the path is "/path", the serialized XML will have </path>value<//path>. This will be treated as syntax error.

Moreover, if the key is user defined complex type, it will mess up the XML syntax further.

In general I think you should probably change the default behavior for map? Because it's causing bugs for some use cases like this.

@HenryYihengXu The question of XML names being invalid is valid, although fix itself cannot be done (nor needs to be done) for just Map values (since format module operates below jackson-databind and has no knowledge of higher level entities).

But one databind-level solution could be to allow alternate Map serialization, to separate key and value. If so, it could work on any format, not just XML (but should work with XML too).

One possible solution added in 2.14 was #531 .

At this point behavior works as intended: if alternate behavior is desired, can file a new issue requesting for specific alternate serialization, along with suggested usage (there has to be some way to opt in to different structure -- current handling needs to remain default for backwards compatibility).