This
<catalog>
<country><![CDATA[ WIN8 <b>X</b> Mac OS ]]></country>
</catalog>
相当于
<catalog>
<country> WIN8 <b>X</b> Mac OS </country>
</catalog>
这正是您使用时得到的
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="country/text()">
<xsl:value-of select="." disable-output-escaping="yes" />
</xsl:template>
</xsl:stylesheet>
重点是disable-output-escaping
(DOE) 对属于以下的元素没有影响cdata-section-elements
(CSE)。这是因为这两个指令都禁用输出转义。
文本值" WIN8 <b>X</b> Mac OS "
变成:
正常序列化时:WIN8 <b>X</b> Mac OS
当使用 CSE 序列化时:<![CDATA[ WIN8 <b>X</b> Mac OS ]]>
当与 DOE 序列化时:WIN8 <b>X</b> Mac OS
请注意最后两个渲染是如何完全相同的,除了封闭的<![CDATA[ ... ]]>
.
CDATA 禁用元素的文本节点子节点的输出转义,并且作为交换将它们包围在<![CDATA[ ... ]]>
标记来弥补逃脱级别的损失。
如果您另外将 DOE 设置为<xsl:value-of>
将文本输出到设置了 CSE 的元素中,但没有任何反应。输出转义已经是禁用。
因此这个
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:output cdata-section-elements="country" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="country/text()">
<xsl:value-of select="." disable-output-escaping="yes" />
</xsl:template>
</xsl:stylesheet>
会给你准确的输入内容。
这就是为什么你无法摆脱双重转义并拥有CDATA
在同一个转变过程中。如果您确实必须在结果文档中包含 CDATA,则可以使用两步方法(第一步禁用输出转义,第二步添加回 CDATA),但我个人认为这是不值得的。