我正在寻找用CDATA块替换转义的XML部分,主要是为了提高XML的可读性,不幸的是,人类必须阅读它。
// Input
def xml = '''
<search>
<search-query>
<nested/<
<xml/<
</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>
'''
答案 0 :(得分:1)
使用此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-section-elements。
答案 1 :(得分:1)
我在Groovy中最接近的是:
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
// Input
def xml = '''
<search>
<search-query>
<nested/>
<xml/>
</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
打印哪些:
<?xml version="1.0" encoding="UTF-8"?>
<search>
<search-query><![CDATA[[<nested/>
<xml/>]]]></search-query>
</search>
答案 2 :(得分:0)
我没有看到内置API可以帮助您的任何方式,因为yield*
方法仅在渲染为String时应用(即:使用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>
<nested/>
<xml/>
</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
不包括Apache commons导入,它非常干净。如果您不想查看嵌套内容周围的空白,可以将unescapeXml(it[1])
更改为unescapeXml(it[1].trim())
如果XML被正确转义(这意味着,在要替换的部分中不显示<
),则仅有效;如果可以,则仅根据元素安全地确定要替换的块。