I have a doubt whether it is possible to ignore the xml root element on a conversion form Object to XML with XStream, or if is there any way to replace the root element with other one, I mean:
I have a function to parse custom runtime-created objects to XML, something like:
public static String entityToXML(GenericResponseObject entity) {
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
xstream.registerConverter(new GenericResponseAttributeConverter());
String xml = xstream.toXML(entity);
return xml;
}
For this, I have made a mess:
I have the GenericResponseObject and the GenericResponseAttribute clases, the idea is to have an object with as many custom attributes as needed on runtime:
@XStreamAlias("objectResult")
public class GenericResponseObject {
@XStreamAlias("attributes")
@XStreamImplicit
private ArrayList<GenericResponseAttribute> attributes;
public GenericResponseObject() {
this.attributes = new ArrayList();
}
public void addAttribute(String name, Object value) {
this.attributes.add(new GenericResponseAttribute(name, value));
}
}
And the class GenericResponseAttribute:
@XStreamAlias("attribute")
public class GenericResponseAttribute {
private String name;
private Object value;
public GenericResponseAttribute(String name, Object value) {
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return this.value;
}
public void setValue(Object value) {
this.value = value;
}
}
And as you can read, every class has their XStream annotations for aliasing and implicit lists, so, let me show you the custom converter I have made for the GenericResponseAttribute class:
public class GenericResponseAttributeConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return type.equals(GenericResponseAttribute.class);
}
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext mc) {
GenericResponseAttribute value = (GenericResponseAttribute)o;
writer.startNode(value.getName());
mc.convertAnother(value.getValue());
writer.endNode();
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext uc) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
So, if I build a GenericResponseObject on runtime, and parse it to XML with my static method, K get something like:
response = new GenericResponseObject();
response.addAttribute("user", "alex");
response.addAttribute("otherAtt", "TEST");
System.out.println(XMLUtil.entityToXML(response));
The result of the println() function is:
<objectResult>
<attribute>
<user>hugo</user>
</attribute>
<attribute>
<otherAtt>TEST</otherAtt>
</attribute>
</objectResult>
Which is almost what I want, but I really need to omit the root element on the GenericResponseAttribute class, its important to say that for the root node that I have shown above, there is always to exist only one node, the attribute name with the content of the attribute value. So, it is going to be a root element always if I delete the current one, for example, the result I need for the previos XML is:
<objectResult>
<user>hugo</user>
<otherAtt>TEST</otherAtt>
</objectResult>
My need is pretty basic, but I don't know how to get it right, I have searched and it seems there's not a method like deletRootNode() or replaceRootNode() in the HierarchicalStreamWriter class, and there's no @XStreamNoRoot or @XStreamMakeRoot annotations that I could use in the GenericResponseAttribute, so, thats why I'm asking here, please help me if you know how to do this.
Thanks.
By the moment I ended up using a String replacement after parsing the object to XML, I mean:
public static String entityToXML(Object entity) {
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
xstream.registerConverter(new GenericResponseAttributeConverter());
String xml = xstream.toXML(entity);
xml = xml.replace("<attribute>", "");
xml = xml.replace("</attribute>", "");
return xml;
}
But, that's not a pretty cool solution, if you have another one please tell me.
Thanks.