Search code examples
xmlgrailsconverters

Grails XML converter add XML from file


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>
  &lt;file&gt;
    &lt;data&gt;..&lt;/data&gt;
    ...
  &lt;/file&gt;
</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?


Solution

  • 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)
                   }
                }