xml-CDATA中的XSL unescape HTML

我正在尝试转换XML

 <catalog>
            <country><![CDATA[ WIN8 &lt;b&gt;X&lt;/b&gt; 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中,则此方法将不起作用.

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

最佳答案
这个

<catalog>
  <country><![CDATA[  WIN8 <b>X</b> Mac OS ]]></country>        
</catalog>

相当于

<catalog>
  <country> WIN8 &lt;b&gt;X&lt;/b&gt; 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>

关键是禁用输出转义(DOE)对属于cdata-section-elements(CSE)的元素没有影响.这是因为两个指令都禁止输出转义.

文本值“ WIN8< b< / b> Mac OS”变为:

>正常序列化时:WIN8< b& gt; X& lt; / b& gt;苹果系统
>当与CSE序列化时:<![CDATA [WIN8< b> X< / b> Mac OS]]>
>当与DOE序列化时:WIN8 b / x苹果系统

请注意,最后两个渲染如何完全相同,只不过包含<![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)-但我个人认为这样做不值得.

转载注明原文:xml-CDATA中的XSL unescape HTML - 代码日志