Имя объекта должно немедленно следовать за символом & & в ссылке на сущность

Я хочу поместить игру packman на мою страницу *.xhtml(я использую jsf 2 и primefaces 3.5)

Однако

когда я "перевел" html-страницу в xhtml, я получаю сообщение об ошибке в этом 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>

В строке:

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

я получаю:

Сущность должна немедленно следовать за символом '&' в сущности ссылка.

Любая идея, как это исправить?

Ответы

Ответ 1

Все ответы, опубликованные до сих пор, дают правильные решения, однако ни один ответ не смог правильно объяснить основную причину конкретной проблемы.

Facelets - это технология представления на основе XML, которая использует XHTML + XML для генерации вывода HTML. XML имеет пять специальных символов, которые имеют особое отношение к синтаксическому анализатору XML:

  • < начало тега.
  • > конец тега.
  • " начало и конец значения атрибута.
  • ' альтернативный старт и конец значения атрибута.
  • & начало объекта (заканчивается на ;).

В случае &, за которым не следует # (например, &#160;, &#xA0; и т.д.), синтаксический анализатор XML неявно ищет один из пяти предопределенные имена сущностей lt, gt, amp, quot и apos, или любое имя, определяемое вручную. Однако в вашем конкретном случае вы использовали & как оператор JavaScript, а не как объект XML. Это полностью объясняет полученную ошибку синтаксического анализа XML:

Сущность должна немедленно следовать за символом '&' в ссылке на объект

В сущности, вы пишете JavaScript-код в другом месте, XML-документ вместо JS файла, поэтому вам следует избегать всех специальных символов XML. & должен быть экранирован как &amp;.

Итак, в вашем конкретном случае

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

должен стать

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

чтобы сделать его действительным для XML.

Однако это затрудняет чтение и обслуживание кода JavaScript. Как указано в Mozilla Developer Network, отличный документ Написание JavaScript для XHTML, вы должны поместить код JavaScript в блок символов (CDATA). Таким образом, в терминах JSF это будет:

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

Парсер XML будет интерпретировать содержимое блока как символьные данные "plain vanilla", а не как XML и, следовательно, интерпретировать специальные символы XML "как есть".

Но гораздо лучше просто поместить JS-код в свой собственный JS файл, который вы включите <script src> или в терминах JSF, <h:outputScript>.

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

(обратите внимание на target="body", таким образом, JSF автоматически отобразит <script> в самом конце <body>, независимо от того, где находится сам <h:outputScript>, тем самым получив тот же эффект, что и с window.onload и $(document).ready(), поэтому вам больше не нужно использовать их в script)

Таким образом, вам не нужно беспокоиться о специальных символах XML в вашем JS-коде. В качестве дополнительного бонуса это дает вам возможность позволить браузеру кешировать JS файл, чтобы уменьшить общий размер ответа.

См. также:

Ответ 2

Вам нужно добавить тэг CDATA внутри тега script, если вы не хотите вручную проходить и избегать всех символов 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>

Ответ 3

Парсер ожидает некоторого содержимого HTML, поэтому он видит & как начало объекта, например &egrave;.

Используйте это обходное решение:

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

поэтому вы указываете, что код не является HTML-текстом, а просто данными, которые будут использоваться как есть.

Ответ 4

Do

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

Ответ 5

Если вы используете XHTML, по какой-то причине обратите внимание, что XHTML 1.0 C 4 говорит: "Используйте внешние скрипты, если ваш script использует &lt, или или или]] > или -." То есть, не вставляйте script код внутри элемента script, а помещайте его в отдельный файл JavaScript и ссылайтесь на него с помощью <script src="foo.js"></script>.