Issue
I have a document structure like this:
<MyDocument>
<MyChildDocument>
<SubElement>
...
</SubElement>
</MyChildDocument>
</MyDocument>
I would like XStream to de-serialise this to the following object:
@XStreamAlias("MyDocument")
public class MyDocument {
String myChildDocument;
public String getMyChildDocument() {
return myChildDocument;
}
public void setMyChildDocument(String str) {
myChildDocument = str;
}
}
The myChildDocument variable should contain the full child document as a string including the tags.
I also need to do the serialisation side of this, avoiding XStream from entity encoding the XML string contained within the myChildDocument variable.
I've been looking at converters to do this for me, but have not found a good way to do it. Any ideas?
Solution
I managed to create a solution for this using a custom converter. In simple terms, when marshalling, feed the XML string for MyChildDocument into an XML reader and use a copier to feed this back out to the writer that is creating the marshalled result. Reverse the process when unmarshalling incoming XML!
public class MyExchangeConverter implements Converter {
protected static XmlPullParser pullParser;
protected static XmlPullParser getPullParser() {
if (pullParser == null) {
try {
pullParser = XmlPullParserFactory.newInstance().newPullParser();
}
catch (XmlPullParserException e) { } // Ah nuts!
}
return pullParser;
}
@Override
public boolean canConvert(@SuppressWarnings("rawtypes") Class type) {
return MyDocument.class.equals(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
MyDocument request = (MyDocument) source;
if (request.getMyChildDocument() != null) {
HierarchicalStreamReader reader;
reader = new XppReader(new StringReader(request.getMyChildDocument()), getPullParser());
HierarchicalStreamCopier copier = new HierarchicalStreamCopier();
copier.copy(reader, writer);
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
MyDocument response = new MyDocument();
reader.moveDown();
Writer out = new StringWriter();
HierarchicalStreamWriter writer = new CompactWriter(out);
HierarchicalStreamCopier copier = new HierarchicalStreamCopier();
copier.copy(reader, writer);
response.setMyChildDocument(out.toString());
reader.moveUp();
return response;
}
}
Some would (rightly) argue this opens up the system to XML injection attacks to a degree. True enough, but for my particular use case, this is not a risk I am concerned about. Just something to be aware of if anybody plans to use this for public facing interfaces with unknown remote parties or the risk of man-in-the-middle attacks. You have been warned!
Answered By - John Rix Answer Checked By - David Goodson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.