实体名称必须紧跟在实体引用中的“&”之后
我想在我的* .xhtml页面上放置一个packman游戏(我使用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 &&
我得到:
实体名称必须紧跟在实体引用中的“&”之后。
任何想法如何解决?
到目前为止发布的所有答案都给出了正确的解决scheme,但没有人能够正确解释具体问题的根本原因。
Facelets是一种基于XML的视图技术,它使用XHTML + XML来生成HTML输出。 XML有五个特殊字符,它们由XMLparsing器进行特殊处理:
- 标签的开始
-
>
标签的结尾。 -
"
一个属性值的开始和结束。 -
'
属性值的替代开始和结束。 -
&
实体的开始(以;
结尾)。
如果&
没有跟在#
(例如 
 
等等),XMLparsing器隐式地查找五个预定义的实体名称 lt
, gt
, amp
, quot
和apos
或任何手动定义的实体名称 。 但是,在您的具体情况下,您使用&
作为JavaScript运算符,而不是XML实体。 这完全解释了你得到的XMLparsing错误:
实体名称必须紧跟在实体引用中的“&”之后
实质上,您是在错误的地方编写JavaScript代码,而不是JS文件的XML文档,所以您应该相应地转义所有的XML特殊字符。 &
必须以&
。
所以,在你的具体情况下,
if (Modernizr.canvas && Modernizr.localstorage &&
必须成为
if (Modernizr.canvas && Modernizr.localstorage &&
使其成为XML有效。
但是,这使JavaScript代码难以阅读和维护。 正如Mozilla开发者networking的优秀文档“为JavaScript编写XHTML”所述 ,您应该将JavaScript代码放在字符数据(CDATA)块中。 因此,在JSF中,这将是:
<h:outputScript> <![CDATA[ // ... ]]> </h:outputScript>
XMLparsing器会将块的内容解释为“普通香草”字符数据,而不是XML,因此将“原样”解释为XML特殊字符。
但是,更好的办法就是把JS代码放在你自己的JS文件中,这个JS文件包含在<script src>
,或者用JSF的术语<h:outputScript>
。
<h:outputScript name="onload.js" target="body" />
(注意target="body"
;通过这种方式,JSF将自动将<script>
放在<body>
,而不pipe<h:outputScript>
本身位于何处,从而达到与window.onload
相同的效果和$(document).ready()
;所以你不需要在脚本中使用这些)
这样你就不用担心你的JS代码中的XML特殊字符。 作为额外的好处,这使您有机会让浏览器cachingJS文件,以使总体响应规模更小。
也可以看看:
- 错误分析/page.xhtml:跟踪错误[line:42]实体“nbsp”被引用,但未声明
- 是否有可能使用JSF + Facelets与HTML 4/5?
- 如何在Facelets模板中引用CSS / JS / image资源?
- 为XHTML编写JavaScript
你需要在脚本标签内部添加一个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>
parsing器需要一些HTML内容,所以它看起来像一个实体的开始,就像è
。
使用此解决方法:
<script type="text/javascript"> // <![CDATA[ Javascript code here // ]]> </script>
所以你指定的代码不是HTML文本,而只是数据被使用。
做
<script>//<![CDATA[ /* script */ //]]></script>
如果您使用XHTML,出于某种原因,请注意, XHTML 1.0 C 4说:“如果您的脚本使用<或&或]]>或 – ”,请使用外部脚本。“也就是说,不要将脚本代码embeddedscript
元素但把它放到一个单独的JavaScript文件中,并用<script src="foo.js"></script>
引用它。