将转义XML文本转换为CDATA节

将转义XML文本转换为CDATA节,xml,groovy,cdata,Xml,Groovy,Cdata,我希望用CDATA块替换转义的XML部分,主要是为了提高XML的可读性,不幸的是,XML必须由人工读取 // Input def xml = ''' <search> <search-query> &lt;nested/&lt; &lt;xml/&lt; </search-query> </search> ''' def search = new XmlParser().parseText(

我希望用CDATA块替换转义的XML部分,主要是为了提高XML的可读性,不幸的是,XML必须由人工读取

// 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>
'''
//输入
def xml=''
嵌套/
xml/
'''
def search=new XmlParser().parseText(xml)
def query=搜索。“搜索查询”
query.replaceNode(){
“搜索查询”(){
//TODO如何在此处添加CDATA区域?
//收益率未调整(“”)
}
}
新的XmlNodePrinter(保留空白:true)。打印(搜索)
//期望
'''
]]>
'''
  • 表现并不重要
  • 我只想在某些元素上使用CDATA

使用此XSLT转换:

<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>


您可以将cdata节元素替换为以空格分隔的元素名称列表。

我看不出内置API有任何帮助,因为
yield*
方法仅在呈现为字符串时适用(即:使用MarkupBuilder)。
replaceNode
方法只创建新的内存中节点,这些节点没有任何方式来表示“原始”内容

但是,考虑到您的示例有限,您可能(不要因为我的建议而对我大喊大叫)最好只进行字符串替换:

// NOTE: using apache commons because I don't think there's a readily
//       accessible XML entity parser in Groovy's core libraries.
@Grab("org.apache.commons:commons-lang3:3.1")
import org.apache.commons.lang3.StringEscapeUtils

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

def converted = xml.replaceAll(/<search-query>([^<]+)<\/search-query/) {
    def value = StringEscapeUtils.unescapeXml(it[1])
    "<search-query><![CDATA[$value]]></search-query>"
}

assert converted == '''
<search>
  <search-query><![CDATA[
    <nested/>
    <xml/>
  ]]></search-query>>
</se
//注意:使用ApacheCommons是因为我认为没有现成的
//Groovy核心库中的可访问XML实体解析器。
@Grab(“org.apache.commons:commons-lang3:3.1”)
导入org.apache.commons.lang3.StringEscapeUtils
//输入
def xml=''
嵌套/
xml/
'''

def converted=xml.replaceAll(/([^我在Groovy中能得到的最接近的值是:

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

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

def nodes = new XmlParser().parseText( xml )

String newXml = XmlUtil.serialize( new groovy.xml.StreamingMarkupBuilder().bind {
  search {
     nodes.'search-query'.each { x ->
      'search-query' {
        mkp.yieldUnescaped "<![CDATA[${x.children()}]]>"
      }
    }
  }
} )

println newXml
import groovy.xml.StreamingMarkupBuilder
导入groovy.xml.XmlUtil
//输入
def xml=''
嵌套/
xml/
'''
def nodes=new XmlParser().parseText(xml)
字符串newXml=XmlUtil.serialize(new groovy.xml.StreamingMarkupBuilder().bind{
搜寻{
节点。'search-query'。每个{x->
“搜索查询”{
mkp.yieldUnescaped“”
}
}
}
} )
println-newXml
其中打印:

<?xml version="1.0" encoding="UTF-8"?>
<search>
  <search-query><![CDATA[[<nested/>
    <xml/>]]]></search-query>
</search>

]]]>

对于这项工作来说,这是一个正确的工具,我需要保留Groovy选项似乎没有做到的空白。最终使用xmlstarlet进行转换:
$xmlstarlet tr cdata.xsl input.xml>output.xml