The entity name must immediately follow the '&' in the entity reference
Asked Answered
M

6

117

I want to put a packman game on my *.xhtml page.(I am using jsf 2 and primefaces 3.5)

However,

when I "translated" the html page in xhtml I get an error at this script:

    <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>

At line:

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

i get:

The entity name must immediately follow the '&' in the entity reference.

Any idea how to fix that?

Merryman answered 30/4, 2013 at 15:40 Comment(0)
B
267

All answers posted so far are giving the right solutions, however no one answer was able to properly explain the underlying cause of the concrete problem.

Facelets is a XML based view technology which uses XHTML+XML to generate HTML output. XML has five special characters which has special treatment by the XML parser:

  • < the start of a tag.
  • > the end of a tag.
  • " the start and end of an attribute value.
  • ' the alternative start and end of an attribute value.
  • & the start of an entity (which ends with ;).

In case of & which is not followed by # (e.g. &#160;, &#xA0;, etc), the XML parser is implicitly looking for one of the five predefined entity names lt, gt, amp, quot and apos, or any manually defined entity name. However, in your particular case, you was using & as a JavaScript operator, not as an XML entity. This totally explains the XML parsing error you got:

The entity name must immediately follow the '&' in the entity reference

In essence, you're writing JavaScript code in the wrong place, a XML document instead of a JS file, so you should be escaping all XML special characters accordingly. The & must be escaped as &amp;.

So, in your particular case, the

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

must become

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

to make it XML-valid.

However, this makes the JavaScript code harder to read and maintain. In case when you want to continue using & instead of &amp; in JavaScript code in a XML document, then you should be placing the JavaScript code in a character data (CDATA) block. Thus, in JSF terms, that would be:

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

The XML parser will interpret the block's contents as "plain vanilla" character data and not as XML and hence interpret the XML special characters "as-is".

But, much better is to just put the JS code in its own JS file which you include by <script src>, or in JSF terms, the <h:outputScript>.

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

(note the target="body"; this way JSF will automatically render the <script> at the very end of <body>, regardless of where <h:outputScript> itself is located, hereby achieving the same effect as with window.onload and $(document).ready(); so you don't need to use those anymore in that script)

This way you don't need to worry about XML-special characters in your JS code. As an additional bonus, this gives you the opportunity to let the browser cache the JS file so that total response size is smaller.

See also:

Bumpy answered 2/5, 2013 at 1:5 Comment(5)
Shouldn't the ![CDATA[ be a commented line? Just curious.Calamine
@Nacho321: Only if the content type is wrongly set to application/xhtml+xml instead of text/html, which in turn would cause several failures in some browsers, mainly MSIE. See also "Writing JavaScript for XHTML" document. In JSF, you don't need to if you use <f:view contentType="text/html"> instead of letting JSF/webbrowser auto-guess do the work. See further also stackoverflow.com/tags/xhtml/infoBumpy
NOTE: This does not only occur for Javascipt operations (since I correctly use &amp;&amp; in an if-statement one line above my error), but also on comment line; my error was on // TODO KevinC & Victor: some todo (now it's changed to and..). Also, thanks a lot for this post. I came across it before as a fix for the same problem as OP.Grussing
your answer is wrong. it should be &amp; instead of &amp;&amp;Zoochemistry
@funky-nd: I guess you confused it with &amp;amp;. Now re-read the answer with this in mind.Bumpy
D
17

You need to add a CDATA tag inside of the script tag, unless you want to manually go through and escape all XHTML characters (e.g. & would need to become &amp;). For example:

<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>
Deas answered 30/4, 2013 at 15:43 Comment(0)
K
13

The parser is expecting some HTML content, so it sees & as the beginning of an entity, like &egrave;.

Use this workaround:

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

so you specify that the code is not HTML text but just data to be used as is.

Kolo answered 30/4, 2013 at 15:44 Comment(0)
G
5

Do

<script>//<![CDATA[
    /* script */
//]]></script>
Groot answered 30/4, 2013 at 15:44 Comment(0)
R
2

If you use XHTML, for some reason, note that XHTML 1.0 C 4 says: “Use external scripts if your script uses < or & or ]]> or --.” That is, don’t embed script code inside a script element but put it into a separate JavaScript file and refer to it with <script src="foo.js"></script>.

Rego answered 30/4, 2013 at 17:8 Comment(0)
B
0

Just in case someone from Blogger arrives, I had this problem when using Beautify extension in VSCode. Don´t use it, don´t beautify it.

Brisance answered 11/10, 2020 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.