javascript XSLTProcessor 有时不工作
-
01-07-2019 - |
题
以下 JavaScript 假设从 XML 文件中读取流行标签,并应用 XSL 样式表并以 HTML 形式输出到浏览器。
function ShowPopularTags() {
xml = XMLDocLoad("http://localhost/xml/tags/popular.xml?s=94987898");
xsl = XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");
if (window.ActiveXObject) {
// code for IE
ex = xml.transformNode(xsl);
ex = ex.replace(/\\/g, "");
document.getElementById("popularTags").innerHTML = ex;
} else if (document.implementation && document.implementation.createDocument) {
// code for Mozilla, Firefox, Opera, etc.
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml, document);
document.getElementById("popularTags").appendChild(resultDocument);
var ihtml = document.getElementById("popularTags").innerHTML;
ihtml = ihtml.replace(/\\/g, "");
document.getElementById("popularTags").innerHTML = ihtml;
}
}
ShowPopularTags();
该脚本的问题是有时它能够输出生成的 HTML 代码,有时却不能。有人知道哪里出了问题吗?
解决方案
您是否被迫使用现在使用的同步解决方案,或者异步解决方案也是一种选择?我记得 Firefox 过去在同步调用方面也遇到过一些问题,而且我不知道其中有多少仍然存在。我见过这样的情况:只要请求正在运行,整个 Firefox 界面就会锁定(根据超时设置,这可能需要很长时间)。
这需要您做更多的工作,但解决方案如下所示。这是我使用 Ajax 处理 XSLT 内容的代码(稍微重写了它,因为我的代码是面向对象的,并且包含一个循环,该循环从首次加载的 XML 文档中解析出适当的 XSL 文档)
笔记:确保在函数外部声明 oCurrentRequest 和 oXMLRequest 的版本,因为它将被继承。
if (window.XMLHttpRequest)
{
oCurrentRequest = new XMLHttpRequest();
oCurrentRequest.onreadystatechange = processReqChange;
oCurrentRequest.open('GET', sURL, true);
oCurrentRequest.send(null);
}
else if (window.ActiveXObject)
{
oCurrentRequest = new ActiveXObject('Microsoft.XMLHTTP');
if (oCurrentRequest)
{
oCurrentRequest.onreadystatechange = processReqChange;
oCurrentRequest.open('GET', sURL, true);
oCurrentRequest.send();
}
}
之后,您只需要一个名为 processReqChange 的函数,其中包含如下内容:
function processReqChange()
{
if (oCurrentRequest.readyState == 4)
{
if (oCurrentRequest.status == 200)
{
oXMLRequest = oCurrentRequest;
oCurrentRequest = null;
loadXSLDoc();
}
}
}
当然,您需要生成第二组函数来处理 XSL 加载(例如,从 loadXSLDoc 开始)。
然后,在 processXSLReqChange 结束时,您可以获取 XML 结果和 XSL 结果并进行转换。
其他提示
好吧,该代码对于 IE 和其他所有东西来说遵循完全不同的路径。我认为问题仅限于其中之一。您在哪些浏览器上尝试过,哪些浏览器出现此错误?
我唯一能想到的另一件事是,当您尝试对其进行操作时,popularTags 元素可能不存在。这个函数是如何执行的呢?在 onload/domready 事件中?
担。IE 执行脚本没有问题。我在 Firefox 中遇到了这个问题。流行标签元素存在于调用该函数的 HTML 文档中。
<div id="popularTags" style="line-height:18px"></div> <script language="javascript" type="text/javascript"> function ShowPopularTags() { xml=XMLDocLoad("http://localhost/xml/tags/popular.xml?s=29497105"); xsl=XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl"); if (window.ActiveXObject){ // code for IE ex=xml.transformNode(xsl); ex = ex.replace(/\\/g, ""); document.getElementById("popularTags").innerHTML=ex; } else if (document.implementation && document.implementation.createDocument){ // code for Mozilla, Firefox, Opera, etc. xsltProcessor=new XSLTProcessor(); xsltProcessor.importStylesheet(xsl); resultDocument = xsltProcessor.transformToFragment(xml,document); document.getElementById("popularTags").appendChild(resultDocument); var ihtml = document.getElementById("popularTags").innerHTML; ihtml = ihtml.replace(/\\/g, ""); document.getElementById("popularTags").innerHTML = ihtml; } } ShowPopularTags(); </script>
为了避免并行加载的问题(如 Dan 所暗示的),最好仅在页面完全加载时调用此类脚本。
理想情况下,您将脚本标签放在页面头部并调用 ShowPopularTags();在正文 Onload 项中。IE。
<BODY onLoad="ShowPopularTags();">
这样您就可以完全确定您的 document.getElementById("popularTags") 不会失败,因为在完全加载包含该元素的 HTML 之前调用脚本。
另外,我们可以看看您的 XMLDocLoad 函数吗?如果它也包含非顺序元素,您可能会遇到这样的问题:XSLT 转换发生在对象 xml 和 xsl 完全加载之前。
以下是 XMLDocLoad 函数。
function XMLDocLoad(fname) { var xmlDoc; if (window.ActiveXObject){ // code for IE xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async=false; xmlDoc.load(fname); return(xmlDoc); } else if(document.implementation && document.implementation.createDocument){ // code for Mozilla, Firefox, Opera, etc. xmlDoc=document.implementation.createDocument("","",null); xmlDoc.async=false; xmlDoc.load(fname); return(xmlDoc); } else{ alert('Your browser cannot handle this script'); } }