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

JavascriptXmlJsfXhtmlFacelets

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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:

Solution 2 - Javascript

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>

Solution 3 - Javascript

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.

Solution 4 - Javascript

Do

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

Solution 5 - Javascript

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

Solution 6 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmaximusView Question on Stackoverflow
Solution 1 - JavascriptBalusCView Answer on Stackoverflow
Solution 2 - JavascriptcdhowieView Answer on Stackoverflow
Solution 3 - JavascriptJacopofarView Answer on Stackoverflow
Solution 4 - JavascriptExplosion PillsView Answer on Stackoverflow
Solution 5 - JavascriptJukka K. KorpelaView Answer on Stackoverflow
Solution 6 - JavascriptdawnView Answer on Stackoverflow