Ім’я сутності має негайно слідувати за знаком „&” у посиланні на об’єкт


91

Я хочу розмістити гру packman на моїй сторінці * .xhtml. (Я використовую jsf 2 і праймфейси 3.5)

Однак

Коли я "перекладаю" сторінку html на xhtml, у цьому сценарії з'являється повідомлення про помилку:

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

я отримав:

Ім’я сутності має негайно слідувати за знаком „&” у посиланні на об’єкт.

Будь-яка ідея, як це виправити?

Відповіді:


219

Усі розміщені досі відповіді дають правильні рішення, проте жодна відповідь не змогла належним чином пояснити основну причину конкретної проблеми.

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 буде інтерпретувати вміст блоку як символьні дані "простий ваніль", а не як 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(); тому вам більше не потрібно використовувати їх у цьому сценарії)

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

Дивіться також:


Чи не повинен! [CDATA [бути коментованим рядком? Просто цікаво.
Nacho321

@ Nacho321: Тільки якщо тип вмісту неправильно встановлений application/xhtml+xmlзамість text/html, що, в свою чергу, може спричинити кілька збоїв у деяких браузерах, переважно MSIE. Див. Також документ "Написання JavaScript для XHTML". У JSF вам не потрібно, якщо ви використовуєте <f:view contentType="text/html">замість того, щоб дозволити JSF / webbrowser автогадування робити роботу. Дивіться далі також stackoverflow.com/tags/xhtml/info
BalusC

ПРИМІТКА: Це відбувається не лише для операцій Javascipt (оскільки я правильно використовую &amp;&amp;в операторі if-рядок один рядок над моєю помилкою), але також і для рядка коментаря; моя помилка була увімкнена // TODO KevinC & Victor: some todo(тепер вона змінена на and..). Крім того, велике спасибі за цей пост. Я натрапляв на це раніше як на вирішення тієї ж проблеми, що і на OP.
Кевін Круйссен,

ваша відповідь неправильна. це має бути & amp; замість & amp; & amp;
стилі фанк,

1
@ funky-nd: Думаю, ви переплутали це з & amp; amp ;. Тепер перечитайте відповідь з урахуванням цього.
BalusC,

14

Вам потрібно додати тег CDATA всередину тегу скрипта, якщо ви не хочете вручну пройти та уникнути всіх символів 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>

12

Синтаксичний аналізатор очікує певного вмісту HTML, тому він розглядає &як початок сутності, наприклад &egrave;.

Використовуйте цей обхідний шлях:

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

отже, ви вказуєте, що код - це не текст HTML, а лише дані, які використовуватимуться як є.



2

Якщо ви використовуєте XHTML, з якихось причин зверніть увагу, що в XHTML 1.0 C 4 сказано: "Використовуйте зовнішні сценарії, якщо ваш скрипт використовує <або & або]]> або -." Тобто, не вбудовуйте код сценарію всередину scriptелемента, а помістіть його в окремий файл JavaScript і посилайтеся на нього за допомогою <script src="foo.js"></script>.


0

На Beautifyвсякий випадок, якщо приїде хтось із Blogger, у мене виникла ця проблема під час використання розширення у VSCode. Не використовуй, не використовуй beautify.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.