我正在尝试转换XML:
<catalog>
<country><![CDATA[ WIN8 <b>X</b> Mac OS ]]></country>
</catalog>
到
<catalog>
<country><![CDATA[ WIN8 <b>X</b> Mac OS ]]></country>
</catalog>
使用XSL转换。
我知道使用disable-output-escaping =“yes”或cdata-section-elements我可以将转义字符转换为非转义字符并放入CDATA内部,但如果字符已经在CDATA中,则无效。
有一个简单的方法吗? 感谢。
答案 0 :(得分:4)
此
<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
:<![CDATA[ WIN8 <b>X</b> Mac OS ]]>
:WIN8 <b>X</b> Mac OS
注意最后两个渲染是如何完全相同的,除了封闭的<![CDATA[ ... ]]>
。
CDATA禁用元素的文本节点子元素的输出转义,交换将它们包含在<![CDATA[ ... ]]>
个标记中,以弥补丢失的转义级别。
如果您在<xsl:value-of>
上另外设置DOE,将文本输出到已设置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 - 但我个人认为这不值得。
答案 1 :(得分:1)
这是另一个解决方案,在xsl:text中使用CDATA with disable-output-escaping =&#34; yes&#34;:
<xsl:template match="/" >
<xsl:text disable-output-escaping="yes"><![CDATA[
<script>
var thisTextIsNotEscaped = "<b>this text is normally escaped, but not in this case</b>";
</script>
]]>
</xsl:text>
</xsl:template>