javascript - 当 XSL 使用 xsl:include 时,如何将 XSL 与 Javascript 一起应用?
问题描述
我正在使用 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?
解决方案
通过 Javascript 在 IE 和 Edge 中使用 XSLT 有点困难,因为最初您将通过使用各种 MSXML(Microsoft 的基于 COM 的 XML、XPath 和 XSLT 1.0 软件包)组件直接与 Microsoft 特定的new ActiveXObject
. 但是,为了与其他浏览器更加兼容,至少在表面上,它们已移至支持XMLHttpRequest
(在 IE 和 Edge 中)和XSLTProcessor
(在 Edge 中),但据我所知,它仍然使用 MSXML 6 ,尤其是对于 XSLT。
由于 MSXML 6 默认将属性设置resolveExternals
为 false 使用xsl:import
和xsl:include
失败,因此要以编程方式使用 MSXML 6(在浏览器中使用 Javascript 执行此操作),您首先需要将该属性设置为 true 以使 MSXML 然后解析并加载外部组件比如导入或包含的样式表模块。当您通过 XMLHttpRequest 加载 XML 时,只有这些属性没有很好地公开。
我没有成功地尝试做到这一点,而没有使用https://martin-honnen.github.io/xslt/2018/test2018112004.html中的太多 IE 特定代码(代码可见new ActiveXObject
于https://github.com /martin-honnen/martin-honnen.github.io/blob/master/xslt/2018/test2018112004.html),但是,当我放弃对 IE 使用 XMLHttpRequest(分别在不支持 XSLTProcessor 的地方)并直接使用所有 MSXML 6 组件时使用并设置上述命名属性,我在 Windows 10 上获得 IE 11 以通过https://martin-honnen.github.io/xslt/2018/test2018112005.html中的 Javascript 解析和使用导入的样式表(代码可见于new ActiveXObject
https://github.com/martin-honnen/martin-honnen.github.io/blob/master/xslt/2018/test2018112005.html)。除了尝试在 IE 11 开发人员工具中使用仿真模式外,我还没有尝试过早期的 IE 版本,因为它也适用于 IE 10 和 9。
所以我在做什么
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);
所以启用xsl:import/xsl:include
。
当然,与您在浏览器中执行的大多数操作一样,默认情况下,同源策略不允许您从任何内容加载 XML,但您的 HTML 与脚本的来源相同。
推荐阅读
- python - Python Tkinter Treeview 固定宽度和可变 SQL 查询
- karate - 如何在空手道响应的黄瓜报告中添加/打印。
- python - 向Hbase插入数据的最快方法是什么?
- android - 如何以编程方式在双卡移动的情况下为双卡获取 CID 和 LAC?
- eclipse-hono - 在 Eclipse-hono 中使用通配符订阅所有租户
- ios - 从基类转换子类,其中子类在 Swift 中具有泛型
- google-analytics-api - 什么情况下会出现这个错误“Restricted dimension(s): ga:userAgeBracket, ga:userGender can only be queried in certain conditions”?
- javascript - 在另一个函数正在执行时阻止函数调用
- kubernetes - Docker 多阶段
- amazon-cloudfront - AWS Route 53 加权路由到两个云端分布