Nazwa jednostki musi znajdować się bezpośrednio po znaku „&” w odniesieniu do jednostki

91

Chcę umieścić grę Packman na mojej stronie * .xhtml (używam jsf 2 i primefaces 3.5)

Jednak,

kiedy "przetłumaczyłem" stronę html na xhtml, pojawia się błąd w tym skrypcie:

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

Na linii:

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

dostaję:

Nazwa jednostki musi znajdować się bezpośrednio po znaku „&” w odniesieniu do jednostki.

Masz jakiś pomysł, jak to naprawić?

maximus
źródło

Odpowiedzi:

219

Wszystkie opublikowane do tej pory odpowiedzi zawierają właściwe rozwiązania, jednak żadna z nich nie była w stanie poprawnie wyjaśnić przyczyny leżącej u podstaw konkretnego problemu.

Facelets to technologia widoku oparta na języku XML, która wykorzystuje XHTML + XML do generowania danych wyjściowych HTML. XML ma pięć znaków specjalnych, które są specjalnie traktowane przez parser XML:

  • < początek tagu.
  • > koniec tagu.
  • " początek i koniec wartości atrybutu.
  • ' alternatywny początek i koniec wartości atrybutu.
  • &początek podmiotu (który kończy się ;).

W przypadku &których nie następuje #(np &#160;, &#xA0;itp), parser XML jest niejawnie szuka jednej z pięciu predefiniowanych nazw jednostki lt , gt, amp, quoti apos, lub dowolny ręcznie zdefiniowana nazwa podmiotu . Jednak w twoim konkretnym przypadku byłeś używany &jako operator JavaScript, a nie jako jednostka XML. To całkowicie wyjaśnia błąd analizy XML, który otrzymałeś:

Nazwa jednostki musi znajdować się bezpośrednio po znaku „&” w odniesieniu do jednostki

Zasadniczo piszesz kod JavaScript w niewłaściwym miejscu, w dokumencie XML zamiast w pliku JS, więc powinieneś odpowiednio uciekać przed wszystkimi znakami specjalnymi XML. &Musi być uciekł jak &amp;.

Tak więc w twoim konkretnym przypadku

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

musi stać się

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

aby był zgodny z XML.

Jednak to sprawia, że ​​kod JavaScript jest trudniejszy do odczytania i utrzymania. Jak stwierdzono w doskonałym dokumencie Mozilla Developer Network Writing JavaScript for XHTML , kod JavaScript należy umieścić w bloku danych znakowych (CDATA). Zatem w kategoriach JSF byłoby to:

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

Parser XML zinterpretuje zawartość bloku jako dane znakowe „zwykłe”, a nie jako XML, a zatem interpretuje znaki specjalne XML „tak jak jest”.

Ale znacznie lepiej jest po prostu umieścić kod JS we własnym pliku JS, który dołączasz za pomocą <script src>lub w terminologii JSF, pliku <h:outputScript>.

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

(zwróć uwagę na target="body"; w ten sposób JSF automatycznie wyrenderuje plik <script>na samym końcu <body>, niezależnie od tego, gdzie <h:outputScript>się znajduje, uzyskując tym samym efekt, co z window.onloadi $(document).ready(); więc nie musisz już ich używać w tym skrypcie)

W ten sposób nie musisz martwić się o znaki specjalne XML w swoim kodzie JS. Jako dodatkowy bonus, daje to możliwość, aby przeglądarka buforowała plik JS, tak aby całkowity rozmiar odpowiedzi był mniejszy.

Zobacz też:

BalusC
źródło
Czy nie powinno! [CDATA [być komentarzem? Po prostu ciekawy.
Nacho321
@ Nacho321: Tylko jeśli typ zawartości jest nieprawidłowo ustawiony na application/xhtml+xmlzamiast text/html, co z kolei spowodowałoby kilka błędów w niektórych przeglądarkach, głównie MSIE. Zobacz także dokument „Writing JavaScript for XHTML”. W JSF nie musisz tego robić, jeśli używasz <f:view contentType="text/html">zamiast pozwalać automatycznemu odgadywaniu JSF / webbrowser działać. Zobacz też: stackoverflow.com/tags/xhtml/info
BalusC
UWAGA: Dzieje się tak nie tylko w przypadku operacji Javascipt (ponieważ poprawnie używam &amp;&amp;w instrukcji if jeden wiersz powyżej mojego błędu), ale także w wierszu komentarza; mój błąd był włączony // TODO KevinC & Victor: some todo(teraz został zmieniony na and…). Wielkie dzięki za ten post. Natknąłem się na to wcześniej jako poprawkę dla tego samego problemu co OP.
Kevin Cruijssen
twoja odpowiedź jest zła. powinno być & amp; zamiast & amp; & amp;
funky-nd
1
@ funky-nd: Myślę, że pomyliłeś to z & amp; amp ;. Teraz ponownie przeczytaj odpowiedź, mając to na uwadze.
BalusC
14

Musisz dodać znacznik CDATA wewnątrz tagu script, chyba że chcesz ręcznie przejść przez wszystkie znaki XHTML i uciec od nich (np. &Musiałby stać się &amp;). Na przykład:

<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>
cdhowie
źródło
12

Parser oczekuje zawartości HTML, więc postrzega go &jako początek jednostki, na przykład &egrave;.

Skorzystaj z tego obejścia:

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

więc określasz, że kod nie jest tekstem HTML, ale tylko danymi, które mają być używane tak, jak są.

Jacopofar
źródło
5

Zrobić

<script>//<![CDATA[
    /* script */
//]]></script>
Pigułki wybuchowe
źródło
2

Jeśli z jakiegoś powodu używasz XHTML, zwróć uwagę, że XHTML 1.0 C 4 mówi: „Użyj zewnętrznych skryptów, jeśli twój skrypt używa <lub & lub]]> lub -.” Oznacza to, że nie należy osadzać kodu skryptu wewnątrz scriptelementu, ale umieścić go w osobnym pliku JavaScript i odnosić się do niego za pomocą <script src="foo.js"></script>.

Jukka K. Korpela
źródło
0

Na wypadek, gdyby pojawił się ktoś z Bloggera, miałem ten problem podczas używania Beautifyrozszerzenia w VSCode. Nie używaj tego, nie używaj beautify.

świt
źródło