Der Entitätsname muss unmittelbar auf das '&' in der Entitätsreferenz folgen

86

Ich möchte ein Packman-Spiel auf meine * .xhtml-Seite setzen (ich verwende jsf 2 und primefaces 3.5).

Jedoch,

Wenn ich die HTML-Seite in xhtml "übersetzt" habe, wird bei diesem Skript eine Fehlermeldung angezeigt:

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

In der Zeile:

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

Ich bekomme:

Der Entitätsname muss unmittelbar auf das '&' in der Entitätsreferenz folgen.

Irgendeine Idee, wie man das behebt?

maximus
quelle

Antworten:

214

Alle bisher veröffentlichten Antworten geben die richtigen Lösungen, jedoch konnte keine Antwort die zugrunde liegende Ursache des konkreten Problems richtig erklären.

Facelets ist eine XML-basierte Ansichtstechnologie, die XHTML + XML verwendet, um HTML-Ausgaben zu generieren. XML hat fünf Sonderzeichen, die vom XML-Parser speziell behandelt werden:

  • < der Beginn eines Tags.
  • > das Ende eines Tags.
  • " Anfang und Ende eines Attributwerts.
  • ' der alternative Anfang und das Ende eines Attributwerts.
  • &der Beginn einer Entität (die mit endet ;).

Im Falle von &denen nicht gefolgt #(zB &#160;, &#xA0;usw.), wird der XML - Parser für eine der fünf implizit suchen vordefinierten Entitätsnamen lt , gt, amp, quotund aposoder jede manuell Entitätsname definiert . In Ihrem speziellen Fall haben Sie jedoch &als JavaScript-Operator und nicht als XML-Entität verwendet. Dies erklärt den XML-Analysefehler, den Sie erhalten haben, vollständig:

Der Entitätsname muss unmittelbar auf das '&' in der Entitätsreferenz folgen

Im Wesentlichen schreiben Sie JavaScript-Code an der falschen Stelle, einem XML-Dokument anstelle einer JS-Datei. Daher sollten Sie alle XML-Sonderzeichen entsprechend maskieren. Das &muss als entkommen werden &amp;.

Also, in Ihrem speziellen Fall die

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

muss werden

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

um es XML-gültig zu machen.

Dies erschwert jedoch das Lesen und Verwalten des JavaScript-Codes. Wie im hervorragenden Dokument von Mozilla Developer Network zum Schreiben von JavaScript für XHTML angegeben , sollten Sie den JavaScript-Code in einen Zeichendatenblock (CDATA) einfügen. In JSF-Begriffen wäre das also:

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

Der XML-Parser interpretiert den Inhalt des Blocks als "Plain Vanilla" -Zeichendaten und nicht als XML und interpretiert daher die XML-Sonderzeichen "wie sie sind".

Viel besser ist es jedoch, den JS-Code einfach in eine eigene JS-Datei einzufügen, die Sie von <script src>oder in JSF-Begriffen einfügen <h:outputScript>.

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

(Beachten Sie target="body"Folgendes: Auf diese Weise rendert JSF das <script>am Ende von automatisch <body>, unabhängig davon, wo es <h:outputScript>sich befindet, und erzielt hiermit den gleichen Effekt wie mit window.onloadund $(document).ready(); Sie müssen diese also nicht mehr in diesem Skript verwenden.)

Auf diese Weise müssen Sie sich keine Gedanken über XML-Sonderzeichen in Ihrem JS-Code machen. Als zusätzlichen Bonus haben Sie die Möglichkeit, die JS-Datei vom Browser zwischenspeichern zu lassen, sodass die Gesamtantwortgröße kleiner ist.

Siehe auch:

BalusC
quelle
Sollte die! [CDATA [nicht eine kommentierte Zeile sein? Nur neugierig.
Nacho321
@ Nacho321: Nur wenn der Inhaltstyp falsch auf application/xhtml+xmlanstatt eingestellt ist text/html, was wiederum in einigen Browsern, hauptsächlich MSIE, zu mehreren Fehlern führen würde. Siehe auch Dokument "Schreiben von JavaScript für XHTML". In JSF müssen Sie dies nicht tun, <f:view contentType="text/html">anstatt JSF / Webbrowser die Arbeit automatisch erraten zu lassen. Siehe weiter auch stackoverflow.com/tags/xhtml/info
BalusC
HINWEIS: Dies tritt nicht nur bei Javascipt-Operationen auf (da ich &amp;&amp;in einer if-Anweisung eine Zeile über meinem Fehler korrekt verwende ), sondern auch in der Kommentarzeile. Mein Fehler war aktiviert // TODO KevinC & Victor: some todo(jetzt wurde er in and.. geändert ). Vielen Dank auch für diesen Beitrag. Ich bin zuvor darauf gestoßen, um das gleiche Problem wie OP zu beheben.
Kevin Cruijssen
Ihre Antwort ist falsch. es sollte & amp sein; anstelle von & amp; & amp;
Funky-nd
1
@ funky-nd: Ich denke du hast es mit & amp; amp; verwechselt. Lesen Sie nun die Antwort in diesem Sinne erneut.
BalusC
14

Sie müssen ein CDATA-Tag innerhalb des Skript-Tags hinzufügen, es sei denn, Sie möchten alle XHTML-Zeichen manuell durchlaufen und maskieren (z. B. &müsste es werden &amp;). Beispielsweise:

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

Der Parser erwartet einige HTML-Inhalte, so dass er &als Anfang einer Entität betrachtet wird, wie z &egrave;.

Verwenden Sie diese Problemumgehung:

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

Sie geben also an, dass der Code kein HTML-Text ist, sondern nur Daten, die unverändert verwendet werden sollen.

Jacopofar
quelle
5

Machen

<script>//<![CDATA[
    /* script */
//]]></script>
Explosionspillen
quelle
2

Wenn Sie XHTML verwenden, beachten Sie aus irgendeinem Grund, dass in XHTML 1.0 C 4 Folgendes angegeben ist: "Verwenden Sie externe Skripte, wenn Ihr Skript <oder & oder]]> oder - verwendet." Das heißt, binden Sie keinen Skriptcode in ein scriptElement ein, sondern fügen Sie ihn in eine separate JavaScript-Datei ein und verweisen Sie mit darauf <script src="foo.js"></script>.

Jukka K. Korpela
quelle