I would like this XML
<root>
<firstTag>
<property key="foo" value="One"/>
<property key="bar" value="Two"/>
</firstTag>
<secondTag>
<property key="foo" value="1"/>
<property key="bar" value="2"/>
</secondTag>
</root>
to be deserialised into a Map<String, String>
such that only the keys and values that are provided via attributes inside the <firstTag/>
are taken into account.
Here is the desired output map:
{foo=One, bar=Two}
And this using XStream, jackson-dataformat-xml, or any popular unmarshalling library.
I needed to implement a Converter
for this:
public class MyConverter implements Converter {
public boolean canConvert(Class clazz) {
return AbstractMap.class.isAssignableFrom(clazz);
}
@Override
public void marshal(Object arg0, HierarchicalStreamWriter writer, MarshallingContext context) {}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
reader.moveDown(); // Get down to the firstTag and secondTag level.
while(reader.hasMoreChildren()) {
if(reader.getNodeName().equals("firstTag")) {
while(reader.hasMoreChildren()) {
reader.moveDown();
String key = reader.getAttribute("key");
String value = reader.getAttribute("value");
map.put(key, value);
reader.moveUp();
}
}
}
return map;
}
}
Then use it:
XStream xstream = new XStream();
xstream.alias("root", java.util.Map.class);
xstream.registerConverter(new MyConverter());
String xml = ...
Map<String, String> map = (Map<String, String>) xstream.fromXML(xml);