原来曾经都是用代码或是像 Velocity 样的模板来转换生成 XML的,自从接触了 XSLT 后,已把它当成了 XML 到其他许多数据格式的不二之选了。有时候因为特殊字符等因素,需要转换后的数据在新节点中用 <![CDATA[...]]> 包裹起来更好看且不易出错,或者还需对生成的 XML 进一步处理时,用 <![[CDATA[...]]> 会更保险些 。
通常我们在 xslt 文件中会这么写:
<description><xsl:value-of select="Description"/></description>
如果原来的 Description 中有特殊字符,如 < 等,转换后,< 会自动变为 < 的,即得到
<description>Hello<Unmi</description>
如果其中是一大段的 html 代码全部变为 < > 等就不怎么直观了,如果用 <![[CDATA[...]]> 就可呈现为原形。再有种情况,如果给 <xsl:value-of> 加个 disable-output-escaping= "yes " 属性,即不对 < 和 > 等符号转义,生成的新的 <description> 将可能是不合法的,例如:
<description>Hello<Unmi</description>,节点间含 < 等符号,不能正确解析。
再者,如果要对生成的 XML 数据作一次纯字符串的操作,不小心置入了特殊字符,该份 XML 将是非法的,所以还是用 <![[CDTA[...]]> 要稳妥。是不直接想过写成这样:
<description><![CDATA[<xsl:value-of select="Description"/>]]></description>
因为 xslt 本身就是个 XML 文档,上面等于把其中的 <xsl:value-of select="Description> 给注释掉了,生成的数据将会是:
<description><xsl:value-of select="Description"/></description>
那么给 <![CDATA[...]]> 的 < 和 > 号转义如何,也就是写成:
<description><![CDATA[<xsl:value-of select="Description"/>]]></description>
得到的结果将会是:
<description> <![CDATA[Hello Unmi></description>
所以说,事情还没有到想当然中那么简单,有什么不决多问问香港的 Google,可以总结出以下两种方法:
1. cdata-section-elements 里写上要用 <![CDATA[...]]> 包裹内容的标签
要写在 <xsl:output 中,比如要让 <description> 标签中的内容包裹上 <![CDATA[...]]> 的话,就写成:
<xsl:output method="xml" cdata-section-elements="description"/>
那么在模板中,仍旧用 <description><xsl:value-of select="Description"/></description>,生成新的 <description> 节点就会是:
<description><![CDATA[Hello Unmi]]></description>
要是多个节点要使用 <![CDATA[...]]>,那就全部列在 cdata-section-elements 中即可,记得是用空格隔开。例如,还有个带命名空间的节点有同样的需求,这样写:
<xsl:output method="xml" indent="yes" cdata-section-elements="description content:encoded"/>
这样可使得 description 和 content:encoded 的数据内容都是 CDATA。有了 <![CDATA[...]]> 的护航,为 <xsl:value-of 里写上 disable-output-escaping="yes" 都不怕了。
2. 手工加上前后的 <![CDATA[ 和 ]]>,用到 disable-output-escaping="yes"
正好可以从前面的例子认识到了 disable-output-escaping="yes" 的效果,是否转义特殊字符,默认为 false,yes 为不转义,是 < 就显示为 <,而不是 < 。具体写的代码复杂了些,多了几行:
1 2 3 4 5 |
<description> <xsl:text disable-output-escaping= "yes"><![CDATA[</xsl:text> <xsl:value-of select="Description"/> <xsl:text disable-output-escaping= "yes">]]></xsl:text> </description> |
这么多行,也就是和 <xsl:output method="xml" cdata-section-elements="description"/> 一样的效果,毋庸置疑,大家都会去选第一种方法。也许你可以让这里的 disable-output-escaping 在其他地方派上用场。
参考:http://topic.csdn.net/t/20061013/10/5079437.html
本文链接 https://yanbin.blog/xslt-generate-cdata-node/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。