问题
I am trying to find a solution to convert a map into root element attributes using XStream.
I do not think this is possible but here is what I have tried to far.
I created a custom converter and attached it to the root object, in the converter I then get access to the map that I am trying to convert into attributes, I iterate through the map and write the attirbute to the node, using writer.addAttribute(entry.getKey(), entry.getValue()); this does actually write the attributes to the root node e.g.
The problem with this approach is that it does not process the rest of the document, it just stops after processing the map, in order to get this to work I need some method of letting the default converter back in control and finish off the model.
The second solution I have been trying to use is to create a custom converter just for the map its self, the problem with this approach is that I can not get a handle to the root element so I can not write to it, is it possible to access the root element this way?
Thanks, Jon
回答1:
Create a converter that writes out the map and falls back on marshalling the object using a reflection converter:
static class MyConverter implements Converter {
private final Map<String, String> attributes;
private final Class<?> clazz;
private final Mapper mapper;
private final ReflectionProvider reflectionProvider;
public MyConverter(Mapper mapper,
ReflectionProvider reflectionProvider, Class<?> clazz,
Map<String, String> attributes) {
super();
this.mapper = mapper;
this.reflectionProvider = reflectionProvider;
this.attributes = attributes;
this.clazz = clazz;
}
@Override
public boolean canConvert(Class cls) {
return cls == clazz;
}
@Override
public void marshal(Object value, HierarchicalStreamWriter writer,
MarshallingContext context) {
for (String key : attributes.keySet()) {
writer.addAttribute(key, attributes.get(key));
}
Converter converter = new ReflectionConverter(mapper,
reflectionProvider);
context.convertAnother(p, converter);
}
@Override
public Object unmarshal(HierarchicalStreamReader arg0,
UnmarshallingContext arg1) {
// TODO Auto-generated method stub
return null;
}
}
Retrieve the Mapper and ReflectionProvider instances from your XStream instance, and register a converter with all necessary setup:
XStream xs = new XStream(new DomDriver());
Mapper mapper = xs.getMapper();
ReflectionProvider reflectionProvider = xs.getReflectionProvider();
xs.alias("youralias", YourRoot.class);
xs.registerConverter(new MyConverter(mapper, reflectionProvider,
YourRoot.class, map));
System.out.println(xs.toXML(yourRoot));
来源:https://stackoverflow.com/questions/7608007/xstream-implicit-map-as-attributes-to-root-element