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

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


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>

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



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


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.