I'm using Grails XML converters to register custom XML marshallers for some domain classes.
There is one class that I need to append XML from a file into the target XML like:
<myobject>
<field1>xxx</field1>
<file>
<data>..</data>
...
</file>
</myobject>
Where field1 is declared on the MyObject, but the file subtree is loaded from a file.
I found two ways of doing this, both are escaping the tags for the file subtree generating:
<myobject>
<field1>xxx</field1>
<file>
<data>..</data>
...
</file>
</myobject>
These methods where with convertAnother and with chars, both produce the same result:
XML.registerObjectMarshaller(MyObject) { o, xml ->
def _file = new File(o.file_name)
xml.build {
field1(o.field1)
xml.startNode 'file'
//xml.convertAnother vf.text
xml.chars vf.text
xml.end()
}
}
Is it possible to add the contents of the file but unescaped?
The only way I found that works is by using the internal writer API of the XML builder:
My code looks exactly like this:
it.registerObjectMarshaller(Contribution) { contribution, xml ->
xml.attribute 'xsi:type', 'CONTRIBUTION'
xml.build {
uid {
value(contribution.uid)
}
contribution.versions.each { version ->
def xml_version = new File(version.fileLocation).text
// remove any internal xml and namespace declaration
xml_version = xml_version.replaceFirst('<\\?xml version="1.0" encoding="UTF-8"\\?>', '')
xml_version = xml_version.replaceFirst('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', '')
xml_version = xml_version.replaceFirst('xmlns="http://schemas.openehr.org/v1"', '')
// change version for versions
xml_version = xml_version.replaceFirst(/<version( )*/, '<versions ')
xml_version = xml_version.replaceFirst('</version>', '</versions>')
// this is what outputs the exact text in the XML
xml.writer.mode = org.grails.web.xml.XMLStreamWriter.Mode.CONTENT
xml.writer.writer.unescaped().write(xml_version)
}
}