实体名称必须紧跟'&'在实体参考中

时间:2013-04-30 15:40:30

标签: javascript xml jsf xhtml facelets

我想在我的* .xhtml页面上放一个打包游戏。(我使用的是jsf 2和primefaces 3.5)

然而,

当我在xhtml中“翻译”html页面时,我在此脚本中收到错误:

    <script>

    var el = document.getElementById("pacman");

    if (Modernizr.canvas && Modernizr.localstorage && 
        Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
      window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
    } else { 
      el.innerHTML = "Sorry, needs a decent browser<br /><small>" + 
        "(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
    }
  </script>

在线:

if (Modernizr.canvas && Modernizr.localstorage && 

我得到:

  

实体名称必须紧跟'&amp;'在实体中   参考

知道如何解决这个问题吗?

6 个答案:

答案 0 :(得分:195)

到目前为止发布的所有答案都给出了正确的解决方案,但没有一个答案能够正确解释具体问题的根本原因。

Facelets是一种基于XML的视图技术,它使用XHTML + XML生成HTML输出。 XML有五个特殊字符,由XML解析器进行特殊处理:

  • <标记的开头。
  • >标记的结尾。
  • "属性值的开头和结尾。
  • '替代属性值的开始和结束。
  • &实体的开头(以;结尾)。

如果&后面没有#(例如&#160;&#xA0;等),则XML解析器会隐式查找五个中的一个{ {3}} ltgtampquotapos,或任何predefined entity names。但是,在您的特定情况下,您使用&作为JavaScript运算符,而不是XML实体。这完全解释了您获得的XML解析错误:

  

实体名称必须紧跟'&amp;'在实体参考

本质上,您在错误的位置编写JavaScript代码,而不是JS文件,因此您应该相应地转义所有XML特殊字符。必须将&转义为&amp;

所以,在你的特定情况下,

if (Modernizr.canvas && Modernizr.localstorage && 

必须成为

if (Modernizr.canvas &amp;&amp; Modernizr.localstorage &amp;&amp;

使其符合XML格式。

然而,这使得JavaScript代码更难以阅读和维护。正如Mozilla Developer Network的优秀文档manually defined entity name中所述,您应该将JavaScript代码放在字符数据(CDATA)块中。因此,在JSF术语中,那将是:

<h:outputScript>
    <![CDATA[
        // ...
    ]]>
</h:outputScript>

XML解析器会将块的内容解释为“普通的vanilla”字符数据,而不是XML,因此可以“按原样”解释XML特殊字符。

但是,更好的方法是将JS代码放在由<script src>包含的JS文件中,或者用JSF术语<h:outputScript>包含。

<h:outputScript name="onload.js" target="body" />

(请注意target="body";这样,无论<script>本身位于何处,JSF都会在<body>的最后自动呈现<h:outputScript>,特此实现与window.onload$(document).ready()相同的效果;因此您不需要在该脚本中再使用它们了

这样您就不必担心JS代码中的XML特殊字符了。作为额外的奖励,这使您有机会让浏览器缓存JS文件,以使总响应大小更小。

另见:

答案 1 :(得分:13)

您需要在脚本标记内添加CDATA标记,除非您想手动浏览并转义所有XHTML字符(例如&需要成为&amp;)。例如:

<script>
//<![CDATA[
var el = document.getElementById("pacman");

if (Modernizr.canvas && Modernizr.localstorage && 
    Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
  window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
} else { 
  el.innerHTML = "Sorry, needs a decent browser<br /><small>" + 
    "(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
}
//]]>
</script>

答案 2 :(得分:12)

解析器需要一些HTML内容,因此它会将&视为实体的开头,例如&egrave;

使用此解决方法:

<script type="text/javascript">
// <![CDATA[
Javascript code here
// ]]>
</script>

因此您指定代码不是HTML文本,而只是指定要按原样使用的数据。

答案 3 :(得分:5)

待办事项

<script>//<![CDATA[
    /* script */
//]]></script>

答案 4 :(得分:2)

如果您出于某种原因使用XHTML,请注意XHTML 1.0 C 4说:“如果您的脚本使用&lt;或者&amp;或]]&gt;或者 - 。“也就是说,不要在script元素中嵌入脚本代码,而是将其放入单独的JavaScript文件中,并使用<script src="foo.js"></script>引用它。

答案 5 :(得分:0)

以防万一来自Blogger的人到达,在VSCode中使用Beautify扩展名时遇到了这个问题。不要使用它,不要beautify