Question

Le code JavaScript suivant suppose de lire les balises populaires d'un fichier XML et applique la feuille de style XSL et la sortie au navigateur au format 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();

Le problème avec ce script est qu’il parvient parfois à sortir le code HTML résultant, parfois non. Quelqu'un sait où va mal?

Était-ce utile?

La solution

Êtes-vous obligé de choisir la solution synchrone que vous utilisez maintenant ou une solution asynchrone est-elle également une option? Je me souviens que Firefox a eu sa part de problèmes avec les appels synchrones dans le passé, et je ne sais pas combien de cela est toujours transporté. J'ai vu des situations dans lesquelles toute l'interface de Firefox resterait bloquée tant que la requête serait en cours d'exécution (ce qui, selon les paramètres de délai d'attente, peut prendre très longtemps).

Cela nécessiterait un peu plus de travail de votre côté, mais la solution ressemblerait à ce qui suit. C’est le code que j’utilise pour gérer les fichiers XSLT avec Ajax (réécrivez-le légèrement car mon code est orienté objet et contient une boucle qui analyse le document XSL approprié dans le document XML chargé en premier).

Remarque: assurez-vous de déclarer votre version de oCurrentRequest et de oXMLRequest en dehors des fonctions, car elle sera reportée.

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();
  }
}

Après cela, vous n’auriez plus besoin que d’une fonction nommée processReqChange contenant quelque chose comme ce qui suit:

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

Et bien sûr, vous aurez besoin de produire un deuxième ensemble de fonctions pour gérer le chargement XSL (en commençant par loadXSLDoc, par exemple).

Ensuite, à la fin du processus XSLReqChange, vous pouvez récupérer votre résultat XML et votre résultat XSL et effectuer la transformation.

Autres conseils

Eh bien, ce code suit des chemins totalement différents pour IE et tout le reste. Je suppose que le problème se limite à l'un d'entre eux. Quels navigateurs avez-vous essayé et quels sont ceux qui affichent cette erreur?

La seule autre chose à laquelle je puisse penser est que l'élément popularTags peut ne pas exister lorsque vous essayez de le modifier. Comment cette fonction est-elle exécutée? Dans un événement onload / domready?

Dan. IE exécute le script sans problème. Je suis confronté au problème dans Firefox. L'élément popularTags existe dans le document HTML qui appelle la fonction.

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

Pour éviter les problèmes de chargement en parallèle (comme l'indique Dan), il est toujours judicieux d'appeler ce type de script uniquement lorsque la page est entièrement chargée.

Idéalement, placez les balises de script dans l'en-tête de page et appelez ShowPopularTags (); dans le corps Onload item. I.e.

<BODY onLoad="ShowPopularTags();">

De cette façon, vous êtes absolument sûr que votre document.getElementById ("popularTags") n'échoue pas car le script est appelé avant que le code HTML contenant l'élément ne soit entièrement chargé.

Aussi, pouvons-nous voir votre fonction XMLDocLoad? Si cela contient également des éléments non séquentiels, vous pouvez être confronté à un problème de transformation XSLT avant que les objets xml et xsl ne soient complètement chargés.

Voici la fonction 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');
    }


}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top