【问题标题】:HTML inside XML CDATA being converted with &lt; and &gt; brackets使用 < 和 > 括号转换 XML CDATA 中的 HTML
【发布时间】:2011-05-17 21:25:52
【问题描述】:

我有一些示例 XML:

<sample><![CDATA[Line 1<br />Line 2<br />Line 3<br />]]></sample>

我正在使用 ASP 使用如下样式表输出此 XML:

Set xmlHttp = Server.CreateObject("Microsoft.XMLHTTP")
xmlHttp.open "GET", URLxml, false
xmlHttp.send()

Set xslHttp = Server.CreateObject("Microsoft.XMLHTTP")
xslHttp.open "GET", xXsl, false
xslHttp.send()   

Set xmlDoc = Server.CreateObject("MICROSOFT.XMLDOM")
Set xslDoc = Server.CreateObject("MICROSOFT.XMLDOM")
xmlDoc.async = false
xslDoc.async = false
xmlDoc.Load xmlHttp.responseXML
xslDoc.Load xslHttp.responseXML

Response.Write xmlDoc.transformNode(xslDoc)

但是,一旦编写完成,HTML 输出将显示为:

Line 1&lt;br /&gt;Line 2&lt;br /&gt;Line 3

我可以看到 ASP 正在转换代码中的括号,但我不知道为什么。有什么想法吗?

【问题讨论】:

  • 好问题,+1。除了@Alejandro 的良好解释,请参阅我的回答,描述该问题的最佳解决方案。
  • +1 问题很明确,并寻求明确的答案 - 注意到,发布 XSL 文档会有所帮助。
  • 输出此数据的 XSL 部分是一个简单的

标签: xml xslt asp-classic cdata


【解决方案1】:

我有一些示例 XML:

<sample><![CDATA[Line 1<br />Line 2<br />Line 3<br />]]></sample>

这是一个带有文本节点子节点的sample元素。

假设您应用了身份转换。那么结果将是:

<sample>Line 1&lt;br /&gt;Line 2&lt;br /&gt;Line 3&lt;br /&gt;</sample>

为什么?因为文本节点和属性值具有特殊字符 &amp;&lt;&gt; 作为字符实体转义。

编辑:当然,你可以使用 DOE...但是,除了它是一个可选功能之外,无论如何结果都会是一个文本节点(没有编码字符实体)。您将需要其他解析器(这在将 HTML 片段输出和编码为 (X)HTML 文档(如提要)时可能很有用,但存在输出格式错误的风险......)。

这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="sample">
        <p>
            <xsl:value-of select="." disable-output-escaping="yes"/>
        </p>
    </xsl:template>
</xsl:stylesheet>

输出:

<p>Line 1<br />Line 2<br />Line 3<br /></p>

呈现为(实际标记):

1号线
2号线
3号线

【讨论】:

  • 但是在 CDATA 语句中不应该按书面形式输出吗?这不是 CDATA 的目的,基本上忽略其中的任何特殊字符吗?
  • CDATA 语句的目的是提供另一种序列化数据的方法。代码块&lt;sample&gt;&lt;![CDATA[&lt;br /&gt;]]&gt;&lt;/sample&gt;&lt;sample&gt;&amp;lt;br /&amp;gt;&lt;/sample&gt; 在语义上是相同的。在这两种情况下,都有一个示例元素,其内容是 &lt;br /&gt; 作为文本字符串,而不是作为元素。 HTML 输出是数据的 HTML 序列化,即使在 HTML 中,您也需要转义 &lt; 字符。
  • @Steve K.:CDATA 部分说:“不要解析这个,把它当作文本”
【解决方案2】:

除了@Alejandro 的解释,这里是最好的解决方案:

切勿将标记放在文本 (CDATA) 节点中

代替:

<sample><![CDATA[Line 1<br />Line 2<br />Line 3<br />]]></sample>

永远创造:

<sample>Line 1<br />Line 2<br />Line 3<br /></sample>

记住:将标记放在 CDATA 中会丢失它。

【讨论】:

    【解决方案3】:

    认为是 XSL 转换给您带来了问题。您应该能够编辑您的 .xsl 文档以更正此问题:

    <xsl:template match=".">
      <xsl:value-of select="." disable-output-escaping="yes" />
      <!-- ... other XSL business here ... -->
    </xsl:template>
    

    我在偷this page about disable output escaping

    为了记录,我讨厌 XML/XSL - 一种寻找问题的解决方案。一般而言,如果您需要处理标记,我发现 XML/XSL 只会引入问题,因为您经常想要处理标记片段,这些片段通常不是有效的 XML,因此您将 CDATA 包装在它周围,然后随着您的欢呼随之而来经历。

    更新

    好的,所以上面没有工作。在添加对问题的评论之前,当然不知道 XSL 是什么样的。以下确实有效(来自this forum thread 的想法):

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text" />
        <xsl:template match=".">
            <xsl:value-of select="sample"  />
        </xsl:template>
    </xsl:stylesheet>
    

    密钥是&lt;xsl:output method="text" /&gt;

    另外,对于否决票,请评论原因。

    【讨论】:

    • @orangepics:是的!始终将未解析的数据视为可解析的数据不是您的问题的一部分...
    • 尝试添加 disable-out-escaping 参数没有成功。似乎 ASP 是实际上在输出上改变它的罪魁祸首。我还发现它正在将 &'s 更改为 &'s ...
    • @orangepips: . 这不是一个有效的模式......另外,你的输出方法是text;这增加了自己构建元素标记的需要......
    • @Alejandro:我认为提问者的标记已经构建,但这可能反映了我不完善的 XSL 知识。当我将该 XSL 应用于此 XML 时:Line 2
      Line 3
      ]]>
      我收到输出 Line 1
      第 2 行
      第 3 行
      .
    • @orangepips:首先,您不能运行转换:. 是无效模式。其次,我倾向于认为 OP 可能想要输出的不仅仅是编码 (X)HTML,即包装 p。您将如何保留您的 text 输出方法?
    猜你喜欢
    • 2013-09-07
    • 2012-02-06
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2010-12-02
    • 2016-05-13
    • 1970-01-01
    相关资源
    最近更新 更多