Question

The following JavaScript supposes to read the popular tags from an XML file and applies the XSL Stylesheet and output to the browser as 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();

The issue with this script is sometime it manages to output the resulting HTML code, sometime it doesn't. Anyone knows where is going wrong?

Was it helpful?

Solution

Are you forced into the synchronous solution you are using now, or is an asynchronous solution an option as well? I recall Firefox has had it's share of problems with synchronous calls in the past, and I don't know how much of that is still carried with it. I have seen situations where the entire Firefox interface would lock up for as long as the request was running (which, depending on timeout settings, can take a very long time).

It would require a bit more work on your end, but the solution would be something like the following. This is the code I use for handling XSLT stuff with Ajax (rewrote it slightly because my code is object oriented and contains a loop that parses out the appropriate XSL document from the XML document first loaded)

Note: make sure you declare your version of oCurrentRequest and oXMLRequest outside of the functions, since it will be carried over.

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

After this you'd just need a function named processReqChange that contains something like the following:

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

And ofcourse you'll need to produce a second set of functions to handle the XSL loading (starting from loadXSLDoc on, for example).

Then at the end of you processXSLReqChange you can grab your XML result and XSL result and do the transformation.

OTHER TIPS

Well, that code follows entirely different paths for IE and everything-else. I assume the problem is limited to one of them. What browsers have you tried it on, and which exhibit this error?

The only other thing I can think of is that the popularTags element may not exist when you're trying to do stuff to it. How is this function being executed? In an onload/domready event?

Dan. IE executes the script with no issue. I am facing the problem in Firefox. The popularTags element exists in the HTML document that calls the function.

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

To avoid problems with things loading in parallel (as hinted by Dan), it is always a good idea to call such scripting only when the page has fully loaded.

Ideally you put the script-tags in the page head and call ShowPopularTags(); in the body Onload item. I.e.

<BODY onLoad="ShowPopularTags();">

That way you are completely sure that your document.getElementById("popularTags") doesn't fail because the scripting is called before the HTML containing the element is fully loaded.

Also, can we see your XMLDocLoad function? If that contains non-sequential elements as well, you might be facing a problem where the XSLT transformation takes place before the objects xml and xsl are fully loaded.

The following is the XMLDocLoad function.

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


}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top