XSLT,JavaScript和未转义的HTML实体

3
我有一个与XSLT、JS和HTML实体有关的小问题,例如在模板中:
<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    for (var i = 0; i &lt; 5; i++) {
        //            ^^^ js error
    }
</script>

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    for (var i = 0; i < 5; i++) {
        //            ^ xslt error
    }
</script>

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    // <![CDATA[
    for (var i = 0; i < 5; i++) {
        //            ^ becomes &lt;
    }
    // ]]>
</script>


<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    for (var i = 0; i <xsl:value-of disable-output-escaping="yes" select="string('&lt;')"/> 5; i++) {
        // works of course
    }
</script>

有人知道我的问题是从哪里来的吗?我一直认为当使用HTML输出方法时,XSLT处理器会保留<script/>元素的内容,而不进行转义...

我在OSX上运行的libxslt2版本为1.1.24,这是通过Macportsports安装的...


抱歉,您没有提供需要翻译的文本。请提供要翻译的英文文本。 - annakata
5个回答

14

好的,长话短说:

看起来对于一些libxslt版本,在使用html输出方法时,xslt处理器不会转义<script/>元素中的内容,而对于其他版本则会。因此建议如下操作:

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    <xsl:text disable-output-escaping="yes">
        // ^ does the trick ...
        for (var i = 0; i < 5; i++) {
            //            ^ works
        }
    </xsl:text>
</script>

嘿!你救了我的命。不,至少节省了我几个小时的时间!谢谢。 - Marcos Buarque
你好,这个问题现在有点老了,但如果您看到这条消息,也许您能帮助我解决问题吗?http://stackoverflow.com/questions/6411376/xslt-disable-output-escaping-not-holding-across-two-diff-servers 这是同样的问题,但您的解决方案可以在我的本地主机上工作,但在我的托管服务器上却无法正常运行。它们似乎具有相同的配置:/ - danjah
2
这在我的情况下不起作用。我收到XSLT错误“元素的内容必须由格式良好的字符数据或标记组成。”,并且它指向带有<的行。 - basZero

4
我一直以为使用HTML输出方法时,XSLT处理器会保留脚本元素的内容不被转义。您是正确的:http://www.w3.org/TR/xslt#section-HTML-Output-Method
The html output method should not perform escaping for the content of the script and style elements.
For example, a literal result element written in the stylesheet as
    <script>if (a &lt; b) foo()</script>
or
    <script><![CDATA[if (a < b) foo()]]></script>
should be output as
    <script>if (a < b) foo()</script>

如果您的XSLT处理器表现不同,那么这是一个错误。但无论如何,避免在嵌入式脚本中使用“<”和“&”都是一个好主意,更好的主意是将所有代码移至链接的.js文件中。

如果XSLT正在生成变量JS脚本,则链接的js文件并不总是可行的,避免使用<和&也不现实。 - annakata
如果看起来像是一个 bug,那么我会尽力缩小范围并提交 bug 报告...感谢你的回答... - Pierre Spring

1

尝试在第三个解决方案的CDATA之前删除双斜杠


1

CDATA块应该可以工作;它们对我来说总是有效的。你的disable-output-escaping值是什么?

更新: 使用Xalan,默认情况下启用disable-output-escaping,我相当确定是no,在我的工作XSL文件中有以下内容:

  • 没有 CDATA 块:

    for (var i = 0; i `&lt;` foo.length; i++) {
    …
    }
    
  • CDATA 块:

    <![CDATA[
    
    for (var i = 0; i < foo.length; i++) { … }
    
    ]]>
    

你的意思是使用以下代码吗:<xsl:value-of disable-output-escaping="yes" select="string('&')"/>这样做可以实现功能,但这不是正确的做法,对吧? - Pierre Spring

0
如果 xsl:output 方法是 html,CDATA 部分将起作用。如果 xsl:output 方法是 xml,则 < 和 > 符号仍将被转换。
为了解决这个问题,您可以使用 xsl:output 元素定义脚本元素不采用此方式。您还可以强制使用 xml 或 html 输出方法。
<xsl:output method="xml" cdata-section-elements="script" />
...
<script type="text/javascript" language="javascript">
<![CDATA[
  for (var i = 0; i &lt; foo.length; i++) { … }
]]>
</script>

这在我的情况下不起作用,我的输出结果是&amp;lt;,而我的输出类型是html - basZero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接