XSL 在 CDATA 中取消转义 HTML

and*_*yro 2 xml xslt cdata html-escape-characters

我正在尝试转换 XML:

 <catalog>
            <country><![CDATA[ WIN8 &lt;b&gt;X&lt;/b&gt; Mac OS ]]></country>
    </catalog>
Run Code Online (Sandbox Code Playgroud)

进入

<catalog>
        <country><![CDATA[  WIN8 <b>X</b> Mac OS ]]></country>        
</catalog>
Run Code Online (Sandbox Code Playgroud)

使用 XSL 转换。

我知道使用disable-output-escaping =“yes”或cdata-section-elements我可以将转义字符转换为未转义并放入CDATA中,但如果字符已经在CDATA中,则这不起作用。

有一个简单的方法吗?谢谢。

Tom*_*lak 5

\n\n
<catalog>\n  <country><![CDATA[  WIN8 <b>X</b> Mac OS ]]></country>        \n</catalog>\n
Run Code Online (Sandbox Code Playgroud)\n\n

相当于

\n\n
<catalog>\n  <country> WIN8 &lt;b&gt;X&lt;/b&gt; Mac OS </country>\n</catalog>\n
Run Code Online (Sandbox Code Playgroud)\n\n

这正是您使用时得到的

\n\n
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n  <xsl:output omit-xml-declaration="yes" indent="yes" />\n\n  <xsl:template match="node() | @*">\n    <xsl:copy>\n      <xsl:apply-templates select="node() | @*" />\n    </xsl:copy>\n  </xsl:template>\n\n  <xsl:template match="country/text()">\n    <xsl:value-of select="." disable-output-escaping="yes" />\n  </xsl:template>\n</xsl:stylesheet>\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

关键是disable-output-escaping(DOE)对于落入cdata-section-elements(CSE)的元素没有影响。这是因为这两个指令都禁用输出转义。

\n\n

文本值" WIN8 <b>X</b> Mac OS "变为:

\n\n
    \n
  • 正常序列化时:WIN8 &lt;b&gt;X&lt;/b&gt; Mac OS

  • \n
  • 当使用 CSE 序列化时:<![CDATA[ WIN8 <b>X</b> Mac OS ]]>

  • \n
  • 当与 DOE 序列化时:WIN8 <b>X</b> Mac OS

  • \n
\n\n

请注意最后两个渲染是如何完全相同的,除了封闭的<![CDATA[ ... ]]>.

\n\n

CDATA 禁用元素的文本节点子节点的输出转义,作为交换,将它们包含在<![CDATA[ ... ]]>标记中以弥补丢失的转义级别。

\n\n

<xsl:value-of>如果您另外在将文本输出到已设置 CSE 的元素中设置 DOE ,则不会发生任何情况。输出转义已被禁用。

\n\n

因此这个

\n\n
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n  <xsl:output omit-xml-declaration="yes" indent="yes" />\n  <xsl:output cdata-section-elements="country" />\n\n  <xsl:template match="node() | @*">\n    <xsl:copy>\n      <xsl:apply-templates select="node() | @*" />\n    </xsl:copy>\n  </xsl:template>\n\n  <xsl:template match="country/text()">\n    <xsl:value-of select="." disable-output-escaping="yes" />\n  </xsl:template>\n</xsl:stylesheet>\n
Run Code Online (Sandbox Code Playgroud)\n\n

会给你准确的输入内容。

\n\n

这就是为什么你无法摆脱双重转义并CDATA 在同一转换期间拥有双重转义。如果您确实必须在结果文档 \xe2\x80\x94 中包含 CDATA,则可以使用两步方法(第一步禁用输出转义,第二步添加回 CDATA),但我个人认为这是不值得的。

\n