La dénomination de l'entité doit immédiatement suivre le " & " dans la référence de l'entité

je veux mettre un jeu packman sur mon *.xhtml page.(J'utilise jsf 2 et primefaces 3.5)

cependant,

quand j'ai "traduit" la page html en xhtml je reçois une erreur à 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 && 

, j'obtiens:

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

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

63
demandé sur BalusC 2013-04-30 19:40:29

5 réponses

toutes les réponses affiché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 de vue basée sur XML qui utilise XHTML+XML pour générer la sortie HTML. XML a cinq caractères spéciaux qui a 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 ; ).

dans le cas de & qui n'est pas suivi de # (par exemple &#160; , &#xA0; , etc), L'analyseur XML recherche implicitement l'un des cinq noms d'entités prédéfinis lt , gt , amp , quot et apos , ou toute nom d'entité défini manuellement . Toutefois, 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:

la dénomination sociale de l'entité doit immédiatement suivre le " & " dans la référence de l'entité

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

Donc, dans votre cas particulier, le

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

doit devenir

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

afin de mettre en XML valide.

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

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

l'analyseur XML interprétera le contenu du bloc comme des données de caractères" simples "et non comme des données XML et, par conséquent, interprétera les caractères spéciaux XML"tels quels".

But, bien mieux est de simplement mettre le code JS dans son propre fichier JS que vous incluez par <script src> , ou en termes de JSF, le <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 soit l'endroit où <h:outputScript> lui-même est situé, réalisant ainsi le même effet qu'avec window.onload et $(document).ready() ; donc vous n'avez plus besoin d'utiliser ceux dans ce script)

ainsi, vous n'avez pas à vous soucier des caractères spéciaux XML dans votre code JS. Comme bonus supplémentaire, cela vous donne l'occasion de laisser le navigateur mettre en cache le fichier JS de sorte que la taille totale de la réponse est plus petite.

voir aussi:

178
répondu BalusC 2017-05-23 11:46:58

vous devez ajouter une balise CDATA à l'intérieur de la balise script, à moins que vous ne vouliez passer et échapper manuellement tous les caractères XHTML (par exemple & devrait 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
répondu cdhowie 2013-04-30 15:43:50

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

utilisez cette solution de contournement:

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

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

11
répondu Jacopofar 2013-04-30 15:44:03

Faire

<script>//<![CDATA[
    /* script */
//]]></script>
5
répondu Explosion Pills 2013-04-30 15:44:41

si vous utilisez XHTML, pour une raison quelconque, notez que XHTML 1.0 C 4 dit:" Utilisez des scripts externes si votre script utilise < or&&]] > ou --."C'est-à-dire, n'incorporez pas de code de script dans un élément script , mais mettez-le dans un fichier JavaScript séparé et reportez-le avec <script src="foo.js"></script> .

2
répondu Jukka K. Korpela 2013-04-30 17:08:10