javascript - XSLT 不适用于 IE 11,不会转换 xml

标签 javascript jquery xml internet-explorer xslt

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

我尝试使用 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() 返回对象不支持属性或方法“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);
        }

    }
});

}

最佳答案

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

关于javascript - XSLT 不适用于 IE 11,不会转换 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41384726/

相关文章:

javascript - JavaScript 和匿名函数中闭包的细节

javascript - 排序 DOM 元素在移动设备(android 浏览器、chrome、safari)上无法正常工作

jquery - 是否可以将自定义 css 类添加到 jQuery UI 对话框上的按钮

java - 如何在异步连接返回时切换 Activity ?

java - 从包名中获取应用程序名

java - 如何将带有命名空间的 XML 字符串解码为 Java 对象

JavaScript - 比较两个数组

javascript - 如何使用 phonegap + quickblox 注册/登录用户?

javascript - 从单独的 JS 文件将 YouTube 视频绑定(bind)到 Div 元素

javascript - 调整 nivo slider 设置不起作用