2016-12-29 85 views
0

试图渲染来自API的XSLT样式表,认为它在Chrome,FF以外的IE上工作正常。XSLT不能在IE 11上工作,不会变换xml

我试过使用w3c的例子,它的工作原理是从文件调用XML和XSLT,而我的AJAX调用成功响应来自这个文件。

W3school样品XSLT sample

我的版本是这样的

function getJson() { 
$.get(url).. 
var json2XMLResult = J2XML.json2xml_str(data); 
getResultXsl(json2XMLResult) 
} 

function getResultXsl(json2xml) { 
    $.get(url) 
     .then(function (data) { 
      let resDefinition = data.Results.ResponseDisplayDefinition; 
      let xmlString = '<?xml version="1.0"?><Response>' + json2xml + '</Response>'; 
      if (typeof DOMParser != "undefined") { 
       parseXml = function (xmlStr) { 
        return (new DOMParser()).parseFromString(xmlStr, "text/xml"); 
       }; 
      } 
      else if (typeof ActiveXObject != "undefined" && 
       new ActiveXObject("Microsoft.XMLDOM")) { 
       parseXml = function (xmlStr) { 
        var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
        xmlDoc.async = "false"; 
        xmlDoc.loadXML(xmlStr); 
        return xmlDoc; 
       }; 
      } 

      else { 
       throw new Error("No XML parser found"); 
      } 

      displayResult(xmlString, resDefinition); 
     }) 
} 

在html显示XSLT,下面alert()确实显示你是否尝试以使其在Chrome或IE浏览器,

function displayResult(xmlStrToConvert, xslStrToConvert) { 
    var xmlConverted = parseXml(xmlStrToConvert); 
    var xslConverted = parseXml(xslStrToConvert); 
    if (window.ActiveXObject || "ActiveXObject" in window) { 
     alert('It is IE but not showing anything'); 
     var ex = xmlConverted.transformNode(xslConverted) 
     $('#xmlJson').append(ex); 
    } else { 
     alert('its not IE'); 
     // code for Chrome, Firefox, Opera, etc. 
     var xsltProcessor = new XSLTProcessor(); 
     xsltProcessor.importStylesheet(xslConverted); 
     var resultDocument = xsltProcessor.transformToFragment(xmlConverted, document); 
     $('#xmlJson').append(resultDocument); 

    } 
} 

也试过var ex= xmlConverted.transformToFragment(xslConverted, document);

有人可以指出这有什么问题吗?也无法在IE11上打开开发工具,这是很难调试,但我可以告诉它的错误与我的代码上面。

编辑 AJAX调用与beforeSend有人可以检查下面的代码是好的,虽然transformNode()正在返回Object doesn't support property or method 'transformNode'XSLTProcessor()没有定义

function transformXML(json2xml) { 
$.ajax({ 
    type: 'GET', 
    url: window.parent.__env.apiManagement + 'Preview/TypeDefinition?objectName=' + apiObjectResponse, 
    beforeSend: function (xhr, settings) { 
     if (window.ActiveXObject) { 
      xhr = new ActiveXObject("Msxml2.XMLHTTP"); 
     } 
     else { 
      xhr = new XMLHttpRequest(); 
     } 
     try { xhr.responseType = "msxml-document"; } catch (err) { } 
    }, 
    success: function (data, status, xhr) { 
     var parseXml = new DOMParser(); 
     var xslStylesheet = parseXml.parseFromString(data.Results.ResponseDisplayDefinition, "text/xml"); 
     var xmlString = '<?xml version="1.0"?><Response>' + json2xml + '</Response>'; 
     var convertedXML = parseXml.parseFromString(xmlString, "text/xml"); 

     // // cross-browser logic omitted for simplicity 
     if(window.ActiveXObject || xhr.responseType == "msxml-document") { 
      var ex = convertedXML.transformNode(xslStylesheet); 
      console.log('>>> ', convertedXML) 
      alert(xmlString) 
      $('#xmlJson').append(ex); 
     } 
     // code for Chrome, Firefox, Opera, etc. 
     else if (document.implementation && document.implementation.createDocument) { 
      var xsltProcessor = new XSLTProcessor(); 
      xsltProcessor.importStylesheet(xslStylesheet); 
      var resultDocument = xsltProcessor.transformToFragment(convertedXML, document); 
      $('#xmlJson').append(resultDocument); 
     } 

    } 
}); 

}

+1

您是否检查了控制台是否存在指向该问题的错误? –

+0

您无法打开开发工具?打开页面之前打开它? – epascarello

+0

由于某种原因无法在IE上打开控制台,它会一直崩溃:/但是当我尝试W3C的示例时,它完美地工作。 – MrNew

回答

1

IE 11支持的DOMParser但使用它会构建一个不支持XSLT的IE XML DOM文档。所以你至少需要改变检查顺序,如果你是为IE编码并且想要做XSLT,那么确保你使用ActiveXObject创建一个MSXML DOM文档,那么你可以使用它的transformNode

你似乎想从字符串解析XML和XSLT,然后使用客户端XSLT转换,我建议使用像在https://martin-honnen.github.io/xslt/2016/test2016123001.html的方法,它不

function parseXmlStringForTransformation(xml) { 
     try { 
      var doc = new ActiveXObject('Msxml2.DOMDocument.6.0'); 
      doc.loadXML(xml); 
      return doc; 
     } 
     catch (e) { 
      var domParser = new DOMParser(); 
      var doc = domParser.parseFromString(xml, 'application/xml'); 
      return doc; 
    } 
    } 

,然后使用XSLTProcessor中,其中支持或相应的MSXML 6的ActiveX API XSLT运行的转变:

function transform(xmlDoc, xslDoc, xsltParams, targetElement) { 
     if (typeof XSLTProcessor !== 'undefined') { 
     var proc = new XSLTProcessor(); 
     proc.importStylesheet(xslDoc); 

     for (var prop in xsltParams) { 
      proc.setParameter(null, prop, xsltParams[prop]); 
     } 

     var resultFrag = proc.transformToFragment(xmlDoc, targetElement.ownerDocument); 

     targetElement.textContent = ''; 
     targetElement.appendChild(resultFrag); 
     } 
     else { 
      var template = new ActiveXObject('Msxml2.XslTemplate.6.0'); 
      template.stylesheet = xslDoc; 
      var proc = template.createProcessor(); 

      for (var prop in xsltParams) { 
      proc.addParameter(prop, xsltParams[prop]); 
      } 

      proc.input = xmlDoc; 

      proc.transform(); 

      var resultHTML = proc.output; 

      targetElement.innerHTML = resultHTML; 
     } 
    } 

然后,您可以使用它作为在

document.addEventListener('DOMContentLoaded', function() { 
    transform(
     parseXmlStringForTransformation('<root>...<\/root>'), 
     parseXmlStringForTransformation('<xsl:stylesheet ...>...<\/xsl:stylesheet>'), 
     { }, // empty parameter object if you don't want to pass parameters from Javascript to XSLT 
     document.getElementById('d1') // target element in your HTML to insert the transformation result into 
    ); 
    }) 
+0

是的,我的意思是w3school不是C,我的不好。但否则上面的代码是正确的?只是需要正确的“if()”? – MrNew

+0

W3school的例子是使用'xhttp'来确定'$ .get()'是否可以访问'xhttp.responseType'? – MrNew

+0

还有其他一些问题,例如'xmlDoc.async'是一个布尔属性,如果你想设置它而不是字符串,那么你应该设置为一个布尔值,但只要你使用'loadXML'解析就可以了无论如何,解析是同步的。我无法分辨JQuery和浏览器DOM/API的混合是否有意义,我不使用JQuery。如果您想要通过HTTP加载XML和XSLT,请参阅http://home.arcor.de/martin.honnen/xslt/test2016081501.html,以获得适用于IE 11,Edge,Chrome和Mozilla的示例。 –