Le nom de l'entité doit immédiatement suivre le «&» dans la référence de l'entité


91

Je veux mettre un jeu packman sur ma page * .xhtml (j'utilise jsf 2 et primefaces 3.5)

cependant,

quand je "traduit" la page html en xhtml, j'obtiens une erreur au niveau de ce 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>

À la ligne:

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

Je reçois:

Le nom de l'entité doit immédiatement suivre le «&» dans la référence de l'entité.

Une idée de comment résoudre ce problème?

Réponses:


219

Toutes les réponses publiées jusqu'à présent donnent les bonnes solutions, mais aucune réponse n'a été en mesure d'expliquer correctement la cause sous-jacente du problème concret.

Facelets est une technologie d'affichage basée sur XML qui utilise XHTML + XML pour générer une sortie HTML. XML a cinq caractères spéciaux qui bénéficient d'un traitement spécial par l'analyseur XML:

  • < le début d'une balise.
  • > la fin d'une balise.
  • " le début et la fin d'une valeur d'attribut.
  • ' le début et la fin alternatifs d'une valeur d'attribut.
  • &le début d'une entité (qui se termine par ;).

En cas de &non suivie par #(par exemple &#160;, &#xA0;etc.), l'analyseur XML est à la recherche implicitement pour l' un des cinq noms d'entités prédéfinies lt , gt, amp, quotet apos, ou tout nom d'entité définie manuellement . Cependant, dans votre cas particulier, vous utilisiez &comme opérateur JavaScript et non comme entité XML. Cela explique totalement l'erreur d'analyse XML que vous avez obtenue:

Le nom de l'entité doit immédiatement suivre le «&» dans la référence de l'entité

En substance, vous écrivez du code JavaScript au mauvais endroit, un document XML au lieu d'un fichier JS, vous devriez donc échapper tous les caractères spéciaux XML en conséquence. Le &doit être échappé comme &amp;.

Donc, dans votre cas particulier, le

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

doit devenir

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

pour le rendre XML valide.

Cependant, cela rend le code JavaScript plus difficile à lire et à maintenir. Comme indiqué dans l'excellent document Writing JavaScript for XHTML de Mozilla Developer Network , vous devriez placer le code JavaScript dans un bloc de données de caractères (CDATA). Ainsi, en termes JSF, ce serait:

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

L'analyseur XML interprètera le contenu du bloc comme des données de caractère "plain vanilla" et non comme XML et interprètera donc les caractères spéciaux XML "tels quels".

Mais, mieux vaut simplement mettre le code JS dans son propre fichier JS que vous incluez par <script src>, ou en termes JSF, le fichier <h:outputScript>.

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

(notez le target="body"; de cette façon JSF rendra automatiquement le <script>à la toute fin de <body>, quel que <h:outputScript>soit son emplacement, obtenant ainsi le même effet qu'avec window.onloadet $(document).ready(); vous n'avez donc plus besoin de les utiliser dans ce script)

De cette façon, vous n'avez pas à vous soucier des caractères spéciaux XML dans votre code JS. En prime, cela vous donne la possibilité de laisser le navigateur mettre en cache le fichier JS afin que la taille totale de la réponse soit plus petite.

Voir également:


Le! [CDATA [ne devrait-il pas être une ligne commentée? Juste curieux.
Nacho321

@ Nacho321: Uniquement si le type de contenu est mal défini au application/xhtml+xmllieu de text/html, ce qui à son tour provoquerait plusieurs échecs dans certains navigateurs, principalement MSIE. Voir aussi le document "Ecrire du JavaScript pour XHTML". Dans JSF, vous n'avez pas besoin de le faire si vous utilisez <f:view contentType="text/html">au lieu de laisser JSF / webbrowser deviner automatiquement faire le travail. Voir aussi stackoverflow.com/tags/xhtml/info
BalusC

REMARQUE: cela ne se produit pas seulement pour les opérations Javascipt (puisque j'utilise correctement &amp;&amp;dans une instruction if une ligne au-dessus de mon erreur), mais également sur la ligne de commentaire; mon erreur était allumée // TODO KevinC & Victor: some todo(maintenant elle est devenue and..). Aussi, merci beaucoup pour ce post. Je suis tombé dessus pour résoudre le même problème que OP.
Kevin Cruijssen

votre réponse est fausse. ce devrait être & amp; au lieu de & amp; & amp;
funky-nd

1
@ funky-nd: Je suppose que vous l'avez confondu avec & amp; amp ;. Maintenant, relisez la réponse en gardant cela à l'esprit.
BalusC

14

Vous devez ajouter une balise CDATA à l'intérieur de la balise de script, à moins que vous ne souhaitiez parcourir et échapper manuellement tous les caractères XHTML (par exemple &devraient devenir &amp;). Par exemple:

<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

L'analyseur attend du contenu HTML, il voit donc &comme le début d'une entité, comme &egrave;.

Utilisez cette solution de contournement:

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

vous spécifiez donc que le code n'est pas du texte HTML mais simplement des données à utiliser telles quelles.



2

Si vous utilisez XHTML, pour une raison quelconque, notez que XHTML 1.0 C 4 dit: "Utilisez des scripts externes si votre script utilise <ou & ou]]> ou -." Autrement dit, n'incorporez pas de code de script dans un scriptélément, mais placez-le dans un fichier JavaScript séparé et faites-y référence avec <script src="foo.js"></script>.


0

Juste au cas où quelqu'un de Blogger arrive, j'ai eu ce problème lors de l'utilisation de l' Beautifyextension dans VSCode. Ne l'utilisez pas, ne l'utilisez pas beautify.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.