Dynamic tag names with JAXB

Viewed 27421

I am using Jersey and JAXB to build a simple RESTful webservice I have a HashMap of 'String' to 'Integer':

2010-04 -> 24 
2010-05 -> 45

I need to generate an XML response which looks like this:

 <map>
   <2010-04>24</2010-04>
   <2010-05>45</2010-05>
 </map>

What is the best way to generate dynamic tag names with JAXB?

3 Answers

Maybe somebody is interested in an easier solution with marshall and unmarshall example. It is not a map but still a key-value solution because we are using JAXBElement with a key (=localname) and value (=textcontent).

@XmlRootElement(name="map")
@XmlAccessorType(XmlAccessType.FIELD)
public class XmlMap {
    //one caveat (as mec_test_1 pointed out) unmarshalled objects are from type org.w3c.dom.Element and during marshall it is JAXBElement
    @XmlAnyElement
    List<JAXBElement<String>> dates = new ArrayList<>();

To unmarshall lets say this xml file

<map>
   <2019-01-01>Yes</2019-01-01>
   <2019-02-01>No</2019-02-01>
</map>

You have to run:

JAXBContext c = JAXBContext.newInstance(XmlMap.class);
XmlMap map = c.createUnmarshaller().unmarshall(new File("xmlfile.xml"));
//access the objects via
System.out.println("Key: " + ((org.w3c.dom.Element) map.dates.get(0)).getLocalName());
System.out.println("Value: " + ((org.w3c.dom.Element) map.dates.get(0)).getTextContent());

An to marshall a object:

import javax.xml.namespace.QName;
import javax.xml.bind.JAXBElement;

XmlMap xmlMap = new XmlMap();
xmlMap.dates.add(new JAXBElement<String>(new QName("key"), String.class, "value"));
xmlMap.dates.add(new JAXBElement<String>(new QName("2019-01-01"), String.class, "Yes"));

JAXBContext context = JAXBContext.newInstance(XmlMap.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(verzObj, System.out);

Output:

<map>
   <key>val</key>
   <2019-01-01>Yes</2019-01-01>
</map>
Related