Hi,
Here is the most convenient and pretty simple solution for the problem I've
implemented so far based on Wolfgang's proposals:
In your JAXB-annotated class you put the following annotations for your map
field:
@XmlRootElement(name="YourClassElementName")
class YourClass {
...
@XmlElement(name="YourMapElementName")
// Here is the trick: Use use special map adapter for maps (see below)
@XmlJavaTypeAdapter(JsonMapAdapter.class)
private Map<String,String> yourMap = new LinkedHashMap<String,String>();
...
}
and the JsonMapAdapter class can be defined somewhere like this:
package your.jaxb.adapters;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
public class JsonMapAdapter extends XmlAdapter<Object, Map<?, ?>> {
@Override
public Map<?, ?> unmarshal(Object domTree) {
Map<Object, Object> map = new LinkedHashMap<Object, Object>();
Element content = (Element) domTree;
NodeList childNodes = content.getChildNodes();
if (childNodes.getLength() > 0) {
for (int i = 0; i < childNodes.getLength(); i++) {
Node child = childNodes.item(i);
String key = child.getNodeName();
// Skip text nodes
if (key.startsWith("#"))
continue;
String value = ((Text) child.getChildNodes().item(0))
.getWholeText();
map.put(key, value);
}
}
return map;
}
@Override
public Object marshal(Map<?, ?> map) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
Element customXml = doc.createElement("Map");
for (Map.Entry<?, ?> entry : map.entrySet()) {
Element keyValuePair = doc.createElement(entry.getKey()
.toString());
keyValuePair.appendChild(doc.createTextNode(entry.getValue()
.toString()));
customXml.appendChild(keyValuePair);
}
return customXml;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
With this approach you only need one additional JAXB-annotation to achieve
the required affect:
@XmlJavaTypeAdapter(JsonMapAdapter.class)
Best,
Leo
--
View this message in context: http://old.nabble.com/Custom-mapping-for-Maps-in-JAXB-tp28779221p28945407.html
Sent from the java.net - jaxb users mailing list archive at Nabble.com.