XSLT不能在IE 11上运行,不会转换xml

时间:2016-12-29 17:45:37

标签: javascript jquery xml internet-explorer xslt

尝试渲染来自API的XSLT样式表,认为它在除了IE之外的Chrome,FF上运行良好。

我尝试使用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上打开开发工具,这很难调试,但我可以告诉我上面的代码有问题。

修改 使用beforeSend进行Ajax调用可以检查以下代码是否正常,但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 :(得分:2)

IE 11支持DOMParser,但使用它构建一个IE XML DOM文档,它不支持XSLT。因此,您至少需要更改检查顺序,如果您正在编写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 XSLT API来运行转换:

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