我想在我的* .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;'在实体中 参考
知道如何解决这个问题吗?
答案 0 :(得分:195)
到目前为止发布的所有答案都给出了正确的解决方案,但没有一个答案能够正确解释具体问题的根本原因。
Facelets是一种基于XML的视图技术,它使用XHTML + XML生成HTML输出。 XML有五个特殊字符,由XML解析器进行特殊处理:
<
标记的开头。>
标记的结尾。"
属性值的开头和结尾。'
替代属性值的开始和结束。&
实体的开头(以;
结尾)。如果&
后面没有#
(例如 
, 
等),则XML解析器会隐式查找五个中的一个{ {3}} lt
,gt
,amp
,quot
和apos
,或任何predefined entity names。但是,在您的特定情况下,您使用&
作为JavaScript运算符,而不是XML实体。这完全解释了您获得的XML解析错误:
实体名称必须紧跟'&amp;'在实体参考
中
本质上,您在错误的位置编写JavaScript代码,而不是JS文件,因此您应该相应地转义所有XML特殊字符。必须将&
转义为&
。
所以,在你的特定情况下,
if (Modernizr.canvas && Modernizr.localstorage &&
必须成为
if (Modernizr.canvas && Modernizr.localstorage &&
使其符合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字符(例如&
需要成为&
)。例如:
<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内容,因此它会将&
视为实体的开头,例如è
。
使用此解决方法:
<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
。