Uncaught TypeError: Failed to execute 'importS

2019-07-12 23:17发布

I am trying to use XSL to translate an XML file into a neat table. For that I used the examples provided by W3schools which can be located here as a starting point. Yet the browser(chrome) is throwing the error that is described in the title of this post. I even tried copying the exact same example on W3 only to be met with the same error. Tried debugging in Firefox, this is the console output
TypeError: Argument 1 of XSLTProcessor.importStylesheet is not an object.

A similar question was posted before and the solution was in changing the model from synchronous to async. I tried doing that through the onreadystatechange method but without success. Here is the code I worked with.

<html>
<head>
<script>
    function loadXMLDoc(filename)
    {
    if (window.ActiveXObject)
      {
      xhttp = new ActiveXObject("Msxml2.XMLHTTP");
      }
    else
      {
      xhttp = new XMLHttpRequest();
      }
    xhttp.onreadystatechange = function() {
        if (xhttp.readyState == 4 && xhttp.status == 200) {
        return xhttp.responseXML;
        }
    };
    xhttp.open("GET", filename);
    try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
    xhttp.send("");
    }

    function displayResult()
    {
    xsl = loadXMLDoc("cdcatalog.xsl");
    xml = loadXMLDoc("cdcatalog.xml");
    // code for IE
    if (window.ActiveXObject || xhttp.responseType == "msxml-document")
      {
      ex = xml.transformNode(xsl);
      document.getElementById("dataTable").innerHTML = ex;
      }
    // code for Chrome, Firefox, Opera, etc.
    else if (document.implementation && document.implementation.createDocument)
      {
      xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet(xsl);
      resultDocument = xsltProcessor.transformToFragment(xml, document);
      document.getElementById("dataTable").appendChild(resultDocument);
      }
    }   
</script>
</head>
<body onload="displayResult()">
<div id="dataTable" />
</body>

Thank you for all the help!

1条回答
在下西门庆
2楼-- · 2019-07-13 00:13

Here is an example of two asynchronous requests where the callback of one event handler starts the next request whose callback does the transformation. To keep it simple, I have used onload instead of onreadystatechange, if you really need support for old IE versions you will need to adapt the code.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest and onload handler with asynchronous requests</title>
<script>
function load(url, callback) {
  var req = new XMLHttpRequest();
  req.open('GET', url);
  // to allow us doing XSLT in IE
  try { req.responseType = "msxml-document" } catch (ex) {}
  req.onload = function() {
    callback(req.responseXML);
  };
  req.send();
}

function transform(xml, xsl) {
  load(
    xml,
    function(inputXml) {
      load(
        xsl,
        function(xsltSheet) {
          displayResult(inputXml, xsltSheet);
        }
      );
    }
  );
}

function displayResult(xmlInput, xsltSheet) {
  if (typeof XSLTProcessor !== 'undefined') {
    var proc = new XSLTProcessor();
    proc.importStylesheet(xsltSheet);
    document.getElementById('example').appendChild(proc.transformToFragment(xmlInput, document));
  }
  else if (typeof xmlInput.transformNode !== 'undefined') {
    document.getElementById("example").innerHTML = xmlInput.transformNode(xsltSheet);
  }
}
</script>
</head>
  <body onload="transform('catalog.xml', 'catalog.xsl')">
<div id="example"></div>
</body>
</html>

Online at http://home.arcor.de/martin.honnen/xslt/test2015072001.html, works fine with current versions of IE, Firefox and Chrome on Windows 8.1.

If you want to start two asynchronous requests directly to load XML and XSLT then you need to do some more work to make sure you know when both documents have been loaded to process them, an example of that is at http://home.arcor.de/martin.honnen/xslt/test2015072101.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest and onload handler with asynchronous requests</title>
<script>
function makeRequest(url, loadedData, property, elementToAddResult) {
  var req = new XMLHttpRequest();
  req.open('GET', url);
  // to allow us doing XSLT in IE
  try { req.responseType = "msxml-document" } catch (ex) {}
  req.onload = function() {
    loadedData[property] = req.responseXML;
    if (checkLoaded(loadedData)) {
      displayResult(loadedData.xmlInput, loadedData.xsltSheet, elementToAddResult);
    };
  };
  req.send();
}  

function checkLoaded(loadedData) {
  return loadedData.xmlInput != null && loadedData.xsltSheet != null;
}

function loadAndTransform(xml, xsl, elementToAddResult) {
  var loadedData = { xmlInput: null, xsltSheet: null };

  makeRequest(xml, loadedData, 'xmlInput', elementToAddResult);
  makeRequest(xsl, loadedData, 'xsltSheet', elementToAddResult);
}  

function displayResult(xmlInput, xsltSheet, elementToAddResult) {
  if (typeof XSLTProcessor !== 'undefined') {
    var proc = new XSLTProcessor();
    proc.importStylesheet(xsltSheet);
    elementToAddResult.appendChild(proc.transformToFragment(xmlInput, document));
  }
  else if (typeof xmlInput.transformNode !== 'undefined') {
    elementToAddResult.innerHTML = xmlInput.transformNode(xsltSheet);
  }
}
</script>
</head>
  <body onload="loadAndTransform('catalog.xml', 'catalog.xsl', document.getElementById('example'));">
<div id="example"></div>
</body>
</html>
查看更多
登录 后发表回答