Search code examples
xmlgroovycdata

Transforming escaped XML text into CDATA sections


I'm looking to replace escaped XML sections with CDATA blocks, mainly to improve the readability of XML that unfortunately has to be read by a human.

// Input
def xml = '''
<search>
  <search-query>
    &lt;nested/&lt;
    &lt;xml/&lt;
  </search-query>
</search>
'''

def search = new XmlParser().parseText(xml)
def query = search."search-query"
query.replaceNode() {
  "search-query"() {
    // TODO how can I add a CDATA section here?
    //yieldUnescaped("<![CDATA[${query.text()}]]>")
  }
}

new XmlNodePrinter(preserveWhitespace:true).print(search)

// Expected
'''
<search>
  <search-query>
    <![CDATA[<nested/>
    <xml/>]]>
  </search-query>
</search>
'''
  • Performance is not important
  • I want to be able to use CDATA on only certain elements

Solution

  • Use this XSLT transformation:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output cdata-section-elements="search-query"/>
    <xsl:template match="/"><xsl:copy-of select="."/></xsl:template>
    </xsl:stylesheet>
    

    You can replace cdata-section-elements with a space-separated list of element names.