实体名称必须紧跟实体引用中的"&"

max*_*mus 74 javascript xml xhtml jsf 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>
Run Code Online (Sandbox Code Playgroud)

在线:

if (Modernizr.canvas && Modernizr.localstorage && 
Run Code Online (Sandbox Code Playgroud)

我得到:

实体名称必须紧跟实体引用中的"&".

知道怎么解决这个问题吗?

Bal*_*usC 201

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

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

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

在箱子&,其后面没有#(例如&#160;,&#xA0;等),XML解析器被隐含找五个一预定义的实体名称 lt,gt,amp,quotapos,或任何手动定义实体名称.但是,在您的特定情况下,您使用的&是JavaScript运算符,而不是XML实体.这完全解释了您获得的XML解析错误:

实体名称必须紧跟实体引用中的"&"

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

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

if (Modernizr.canvas && Modernizr.localstorage && 
Run Code Online (Sandbox Code Playgroud)

必须成为

if (Modernizr.canvas &amp;&amp; Modernizr.localstorage &amp;&amp;
Run Code Online (Sandbox Code Playgroud)

使其具有XML有效性.

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

<h:outputScript>
    <![CDATA[
        // ...
    ]]>
</h:outputScript>
Run Code Online (Sandbox Code Playgroud)

XML解析器将块的内容解释为"普通的vanilla"字符数据而不是XML,因此将"特殊字符"解释为"原样".

但是,更好的是将JS代码放在它自己的JS文件中<script src>,或者用JSF术语表示<h:outputScript>.

<h:outputScript name="onload.js" target="body" />
Run Code Online (Sandbox Code Playgroud)

(请注意target="body",这样JSF会自动呈现<script>在最末端<body>,无论在哪里,<h:outputScript>自己的位置,在此实现为具有相同的效果window.onload$(document).ready(),因此你不需要在脚本中不再使用那些)

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

也可以看看:

  • 这就像你第100次在SO中解决我的生活.你是无所不在的!你总是很清楚.@BalusC就是男人. (4认同)
  • 我喜欢你简化的事情.谢谢你打破了它. (3认同)
  • @funky-nd:我猜你把它与 &amp;amp; 混淆了。现在记住这一点,重新阅读答案。 (2认同)

cdh*_*wie 14

您需要在脚本标记内添加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>
Run Code Online (Sandbox Code Playgroud)


Jac*_*far 12

解析器期待一些HTML内容,因此它被&视为实体的开头,如&egrave;.

使用此解决方法:

<script type="text/javascript">
// <![CDATA[
Javascript code here
// ]]>
</script>
Run Code Online (Sandbox Code Playgroud)

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


Exp*_*lls 5

<script>//<![CDATA[
    /* script */
//]]></script>
Run Code Online (Sandbox Code Playgroud)