Pergunta

A seguir JavaScript supõe para ler os tags mais populares de um arquivo XML e aplica a folha de estilo XSL e saída para o navegador como HTML.

function ShowPopularTags() {
   xml = XMLDocLoad("http://localhost/xml/tags/popular.xml?s=94987898");
   xsl = XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");
   if (window.ActiveXObject) {
      // code for IE
      ex = xml.transformNode(xsl);
      ex = ex.replace(/\\/g, "");
      document.getElementById("popularTags").innerHTML = ex;
   } else if (document.implementation && document.implementation.createDocument) {
      // code for Mozilla, Firefox, Opera, etc.
      xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet(xsl);
      resultDocument = xsltProcessor.transformToFragment(xml, document);
      document.getElementById("popularTags").appendChild(resultDocument);
      var ihtml = document.getElementById("popularTags").innerHTML;
      ihtml = ihtml.replace(/\\/g, "");
      document.getElementById("popularTags").innerHTML = ihtml;
   }
}
ShowPopularTags();

O problema com este script é em algum momento ele consegue saída o código HTML resultante, em algum momento isso não acontece. Alguém sabe onde está indo errado?

Foi útil?

Solução

Você é obrigado na solução síncrona que você está usando agora, ou é uma solução assíncrona uma opção bem? Lembro-me de Firefox teve quota de problemas com chamadas síncronas no passado, e eu não sei o quanto de que ainda é realizada com ele. Já vi situações em que toda a interface do Firefox poderia bloquear-se durante o tempo que o pedido foi executado (que, dependendo das configurações de tempo limite, pode levar um tempo muito longo).

Seria necessário um pouco mais de trabalho em sua extremidade, mas a solução seria algo como o seguinte. Este é o uso I código para lidar com coisas XSLT com Ajax (reescreveu-lo um pouco, porque o meu código é orientado a objeto e contém um loop que analisa o documento XSL apropriado a partir do documento XML carregado pela primeira vez)

Nota: Certifique-se de declarar a sua versão do oCurrentRequest e oXMLRequest fora das funções, uma vez que irá transitar

.
if (window.XMLHttpRequest)
{
  oCurrentRequest = new XMLHttpRequest();
  oCurrentRequest.onreadystatechange = processReqChange;
  oCurrentRequest.open('GET', sURL, true);
  oCurrentRequest.send(null);
}
else if (window.ActiveXObject)
{
  oCurrentRequest = new ActiveXObject('Microsoft.XMLHTTP');
  if (oCurrentRequest)
  {
    oCurrentRequest.onreadystatechange = processReqChange;
    oCurrentRequest.open('GET', sURL, true);
    oCurrentRequest.send();
  }
}

Depois disto você só precisa de uma função chamada processReqChange que contém algo como o seguinte:

function processReqChange()
{
  if (oCurrentRequest.readyState == 4)
  {
    if (oCurrentRequest.status == 200)
    {
      oXMLRequest = oCurrentRequest;
      oCurrentRequest = null;
      loadXSLDoc();
    }
  }
}

E claro que você vai precisar para produzir um segundo conjunto de funções para lidar com a carga de XSL (a partir de loadXSLDoc sobre, por exemplo).

Então, no final de você processXSLReqChange você pode pegar o seu resultado XML e XSL resultado e fazer a transformação.

Outras dicas

Bem, isso código segue caminhos completamente diferentes para IE e tudo-else. Presumo que o problema está limitado a um deles. Quais navegadores você já tentou-o, e que exibem esse erro?

A única outra coisa que eu posso pensar é que o elemento popularTags não pode existir quando você está tentando fazer coisas para ele. Como é que esta função que está sendo executado? Em um / evento domready onload?

Dan. IE executa o script com nenhum problema. Eu estou enfrentando o problema no Firefox. O elemento popularTags existe no documento HTML que chama a função.

<div id="popularTags" style="line-height:18px"></div>
<script language="javascript" type="text/javascript">
    function ShowPopularTags()
    {
        xml=XMLDocLoad("http://localhost/xml/tags/popular.xml?s=29497105");
        xsl=XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");

        if (window.ActiveXObject){
            // code for IE
            ex=xml.transformNode(xsl);
            ex = ex.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML=ex;
        }
        else if (document.implementation && document.implementation.createDocument){
            // code for Mozilla, Firefox, Opera, etc.
            xsltProcessor=new XSLTProcessor();
            xsltProcessor.importStylesheet(xsl);
            resultDocument = xsltProcessor.transformToFragment(xml,document);
            document.getElementById("popularTags").appendChild(resultDocument);

            var ihtml = document.getElementById("popularTags").innerHTML;
            ihtml = ihtml.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML = ihtml;
         }
    }

    ShowPopularTags();
</script>    

Para evitar problemas com as coisas de carga em paralelo (como sugerido por Dan), é sempre uma boa idéia para chamar tais scripting apenas quando a página foi totalmente carregado.

O ideal é colocar o script-tags na cabeça da página e ShowPopularTags call (); no item OnLoad corpo. I.

<BODY onLoad="ShowPopularTags();">

Dessa forma, você está completamente certo de que seus document.getElementById ( "popularTags") não falha porque o script é chamado antes do HTML que contém o elemento está totalmente carregado.

Além disso, podemos ver a sua função XMLDocLoad? Se que contém elementos não-seqüenciais, bem como, você pode estar enfrentando um problema onde a transformação XSLT ocorre antes dos objetos XML e XSL são totalmente carregado.

A seguir é a função XMLDocLoad.

function XMLDocLoad(fname)
{
    var xmlDoc;

    if (window.ActiveXObject){
        // code for IE
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async=false;
        xmlDoc.load(fname);

        return(xmlDoc);
    }
    else if(document.implementation && document.implementation.createDocument){
        // code for Mozilla, Firefox, Opera, etc.
        xmlDoc=document.implementation.createDocument("","",null);

        xmlDoc.async=false;
        xmlDoc.load(fname);

        return(xmlDoc);

    }
    else{
        alert('Your browser cannot handle this script');
    }


}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top