Mark
Mark

Reputation: 5239

Converting HashMap<String, List<String>> to XML with JAXB

I'm trying to marshall an object into XML, this object extends HashMap<String, List<String>>. However it's unclear to me as to why the output does not contain the data entered in this object. The method used to marshall this object into XML can be found near the end of the question.

Example 1 (actual situation)

Data structure:

@XmlRootElement
class WhatIWant extends HashMap<String, List<String>> {

}

Which is filled using:

WhatIWant what = new WhatIWant();
what.put("theKey", Arrays.asList("value1", "value2"));

The resulting output is as follows, the data entered is nowhere to be found.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<whatIWant/>

Example 2 (situation which generates expected result)

Something like this does work and is what I expected the output of the first example to look similar to.

Data structure:

@XmlRootElement
class MyHashmap {
    public HashMap<String, MyList> map = new HashMap<>();
}

class MyList {
    public List<String> list = new ArrayList<String>();
}

Filled using:

MyHashmap requirement = new MyHashmap();
MyList t = new MyList();
t.list = Arrays.asList("value1", "value2");
requirement.map.put("theKey", t);

The resulting output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myHashmap>
    <map>
        <entry>
            <key>theKey</key>
            <value>
                <list>value1</list>
                <list>value2</list>
            </value>
        </entry>
    </map>
</myHashmap>

Object to XML method

The method which I used to turn the objects into XML:

public static String getObjectAsXML(Object obj) {
    try {
        // Create marshaller
        JAXBContext context = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        // Marshall the object
        StringWriter sw = new StringWriter();
        marshaller.marshal(obj, sw);

        return sw.toString();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

The question

  1. Why does Example 1 not generate output similar to the one in Example 2? Why does not not generate anything at all?
  2. What should be done to get XML output for a structure like Example 1? Or is this not possible?

Upvotes: 1

Views: 1127

Answers (1)

TacheDeChoco
TacheDeChoco

Reputation: 3913

The reason might be because of the following: The elements to be marshalled/unmarshalled must be public, or have the XMLElement annotation.

In your first example, the root class has no public elements, while the second does. You could try to add (to the first example) a public getter returning the map entries (and add appropriate @XmlAccessorType to the WhatIWant class) and see if it gives the expected results

Upvotes: 1

Related Questions