O nome da entidade deve seguir imediatamente o '&' na referência da entidade

92

Quero colocar um jogo packman na minha página * .xhtml. (Estou usando jsf 2 e primefaces 3.5)

Contudo,

quando "traduzi" a página html em xhtml recebo um erro neste 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>

Na linha:

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

eu recebo:

O nome da entidade deve seguir imediatamente o '&' na referência da entidade.

Alguma ideia de como consertar isso?

maximus
fonte

Respostas:

220

Todas as respostas postadas até agora fornecem as soluções corretas, mas nenhuma resposta foi capaz de explicar adequadamente a causa subjacente do problema concreto.

Facelets é uma tecnologia de visualização baseada em XML que usa XHTML + XML para gerar saída HTML. XML possui cinco caracteres especiais que têm tratamento especial pelo analisador XML:

  • < o início de uma tag.
  • > o fim de uma tag.
  • " o início e o fim de um valor de atributo.
  • ' o início e o fim alternativos de um valor de atributo.
  • &o início de uma entidade (que termina com ;).

Em caso de &que não é seguido por #(por exemplo &#160;, &#xA0;, etc), o analisador XML é implicitamente à procura de um dos cinco nomes de entidades predefinidas lt , gt, amp, quote apos, ou qualquer nome de entidade definida manualmente . No entanto, em seu caso específico, você estava usando &como um operador JavaScript, não como uma entidade XML. Isso explica totalmente o erro de análise de XML que você obteve:

O nome da entidade deve seguir imediatamente o '&' na referência da entidade

Em essência, você está escrevendo código JavaScript no lugar errado, um documento XML em vez de um arquivo JS, então você deve escapar todos os caracteres especiais XML de acordo. O &deve ser escapado como &amp;.

Então, em seu caso particular, o

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

deve se tornar

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

para torná-lo válido para XML.

No entanto, isso torna o código JavaScript mais difícil de ler e manter. Conforme declarado no excelente documento do Mozilla Developer Network, Writing JavaScript for XHTML , você deve colocar o código JavaScript em um bloco de dados de caracteres (CDATA). Assim, em termos de JSF, isso seria:

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

O analisador XML interpretará o conteúdo do bloco como dados de caractere "plain vanilla" e não como XML e, portanto, interpretará os caracteres especiais XML "no estado em que se encontram".

Mas, muito melhor é apenas colocar o código JS em seu próprio arquivo JS que você inclui por <script src>, ou em termos JSF, o <h:outputScript>.

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

(observe o target="body"; desta forma, o JSF renderizará automaticamente o <script>no final de <body>, independentemente de onde <h:outputScript>ele esteja localizado, obtendo assim o mesmo efeito que com window.onloade $(document).ready(); portanto, você não precisa mais usá-los nesse script)

Dessa forma, você não precisa se preocupar com caracteres especiais XML em seu código JS. Como um bônus adicional, isso dá a oportunidade de permitir que o navegador armazene em cache o arquivo JS para que o tamanho total da resposta seja menor.

Veja também:

BalusC
fonte
Não deveria o! [CDATA [ser uma linha comentada? Apenas curioso.
Nacho321
@ Nacho321: Somente se o tipo de conteúdo for definido incorretamente como em application/xhtml+xmlvez de text/html, o que, por sua vez, causaria várias falhas em alguns navegadores, principalmente MSIE. Consulte também o documento "Escrevendo JavaScript para XHTML". No JSF, você não precisa se usar em <f:view contentType="text/html">vez de permitir que o JSF / webbrowser faça o trabalho automaticamente. Consulte também stackoverflow.com/tags/xhtml/info
BalusC de
NOTA: Isso não ocorre apenas para operações Javascipt (já que eu uso corretamente &amp;&amp;em uma instrução if uma linha acima do meu erro), mas também na linha de comentário; meu erro foi ativado // TODO KevinC & Victor: some todo(agora mudou para and..). Além disso, muito obrigado por este post. Eu encontrei isso antes como uma solução para o mesmo problema do OP.
Kevin Cruijssen
sua resposta está errada. deve ser & amp; em vez de & amp; & amp;
funky-nd
1
@ funky-nd: Acho que você o confundiu com & amp; amp ;. Agora releia a resposta com isso em mente.
BalusC
14

Você precisa adicionar uma tag CDATA dentro da tag do script, a menos que queira passar manualmente e escapar de todos os caracteres XHTML (por exemplo &, precisariam se tornar &amp;). Por exemplo:

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

O analisador está esperando algum conteúdo HTML, portanto, ele vê &como o início de uma entidade, como &egrave;.

Use esta solução alternativa:

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

portanto, você especifica que o código não é um texto HTML, mas apenas dados a serem usados ​​como estão.

Jacopofar
fonte
5

Faz

<script>//<![CDATA[
    /* script */
//]]></script>
Pílulas de explosão
fonte
2

Se você usar XHTML, por algum motivo, observe que XHTML 1.0 C 4 diz: “Use scripts externos se seu script usar <ou & ou]]> ou -.” Ou seja, não incorpore o código de script dentro de um scriptelemento, mas coloque-o em um arquivo JavaScript separado e consulte-o com <script src="foo.js"></script>.

Jukka K. Korpela
fonte
0

Caso chegue alguém do Blogger, tive esse problema ao usar Beautifyextensão no VSCode. Não use, não use beautify.

alvorecer
fonte