当XSL使用xsl:include时,如何在Javascript中应用XSL?

时间:2018-11-20 17:49:24

标签: javascript xml xslt

我正在使用W3Schools上的XSLT代码示例:https://www.w3schools.com/xml/xsl_client.asp

我有这部分代码在IE中使用基本的xslt处理...

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

function displayResult()
{
xml = loadXMLDoc("cdcatalog.xml");
xsl = loadXMLDoc("cdcatalog.xsl");
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
  {
  ex = xml.transformNode(xsl);
  document.getElementById("example").innerHTML = ex;
  }
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html> 

问题是我正在扩展此解决方案的XSL具有复杂的结构,因此有多个xsl:include语句可以引入其他xsl模板(https://www.w3schools.com/xml/ref_xsl_el_include.asp)。 Javascript未处理xsl:include导入,而XSLT处理器不断抱怨缺少模板。

如何获取Javascript处理xsl:include?

1 个答案:

答案 0 :(得分:1)

通过javascript在IE和Edge中使用XSLT有点困难,因为最初您可以通过直接将各种MSXML(基于Microsoft COM的XML,XPath和XSLT 1.0软件包)组件与特定于Microsoft的{{1 }}。但是,为了与其他浏览器更加兼容,它们至少在表面上已迁移为支持new ActiveXObject(在IE和Edge中)和XMLHttpRequest(在Edge中),但据我所知引擎盖仍然使用MSXML 6,尤其是XSLT。

由于默认情况下MSXML 6将属性XSLTProcessor设置为false,因此resolveExternalsxsl:import的使用失败,因此请以编程方式使用MSXML 6(在浏览器中使用Javascript进行操作)您首先需要将该属性设置为true,以拥有MSXML,然后解析并加载外部组件,例如导入的或包含的样式表模块。通过XMLHttpRequest加载XML时,只有这些属性无法很好地公开。

我尝试通过在https://martin-honnen.github.io/xslt/2018/test2018112004.html中使用xsl:include(在https://github.com/martin-honnen/martin-honnen.github.io/blob/master/xslt/2018/test2018112004.html可见的代码)而没有使用过多的IE专用代码(在https://martin-honnen.github.io/xslt/2018/test2018112005.html可见)来完成此操作,但是,当我放弃使用针对IE的XMLHttpRequest(分别不支持XSLTProcessor的地方),并直接将所有MSXML 6组件与new ActiveXObject一起使用并设置上述命名属性,我在Windows 10上获得IE 11,以通过{{ 3}}(代码在https://github.com/martin-honnen/martin-honnen.github.io/blob/master/xslt/2018/test2018112005.html上可见)。除了尝试在IE 11开发人员工具中使用仿真模式之外,我还没有尝试过使用较早的IE版本,因为它也可以在IE 10和9中使用。

所以我要做的

new ActiveXObject

正在直接使用 function loadDocForXslt(url) { return new Promise(function(resolve) { if (typeof XSLTProcessor === 'undefined') { var doc = new ActiveXObject('Msxml2.DOMDocument.6.0'); doc.setProperty('ResolveExternals', true); doc.onreadystatechange = function() { if (doc.readyState === 4) { resolve(doc); } }; doc.load(url); } else { var req = new XMLHttpRequest(); req.open("GET", url); if (typeof XSLTProcessor === 'undefined') { try { req.responseType = 'msxml-document'; } catch (e) {} } req.onload = function() { resolve(this.responseXML) } req.send(); } }); } 创建一个MSXML 6 XML DOM文档,并将其设置为属性new ActiveXObject('Msxml2.DOMDocument.6.0'),因此启用doc.setProperty('ResolveExternals', true);

当然,与您在浏览器中所做的大多数事情一样,默认情况下,相同的原始策略不允许您从任何内容加载XML,但与脚本所用的HTML相同的原始来源。