1

下面的 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 代码,有时却没有。有谁知道哪里出了问题?

4

5 回答 5

1

为了避免并行加载的问题(正如 Dan 所暗示的),仅在页面完全加载时调用此类脚本总是一个好主意。

理想情况下,您将脚本标签放在页眉中并调用 ShowPopularTags(); 在正文 Onload 项中。IE

<BODY onLoad="ShowPopularTags();">

这样您就可以完全确定您的 document.getElementById("popularTags") 不会失败,因为在包含该元素的 HTML 完全加载之前调用了脚本。

另外,我们可以看看你的 XMLDocLoad 函数吗?如果其中还包含非顺序元素,您可能会遇到 XSLT 转换发生在对象 xml 和 xsl 完全加载之前发生的问题。

于 2008-09-19T10:50:17.687 回答
1

您是被迫使用现在正在使用的同步解决方案,还是异步解决方案也是一种选择?我记得 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 结果并进行转换。

于 2008-09-21T12:04:02.740 回答
0

好吧,对于 IE 和其他所有内容,该代码遵循完全不同的路径。我认为问题仅限于其中之一。您在哪些浏览器上尝试过,哪些浏览器出现此错误?

我唯一能想到的另一件事是,当您尝试对其进行处理时,popularTags 元素可能不存在。这个函数是如何执行的?在 onload/domready 事件中?

于 2008-09-19T10:09:49.547 回答
0

担。IE 执行脚本没有问题。我在 Firefox 中遇到了这个问题。popularTags 元素存在于调用该函数的 HTML 文档中。

<div id="popularTags" style="line-height:18px"></div>
<script language="javascript" type="text/javascript">
    函数 ShowPopularTags()
    {
        xml=XMLDocLoad("http://localhost/xml/tags/popular.xml?s=29497105");
        xsl=XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");

        如果(窗口。ActiveXObject){
            // IE代码
            ex=xml.transformNode(xsl);
            ex = ex.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML=ex;
        }
        else if (document.implementation && document.implementation.createDocument){
            // Mozilla、Firefox、Opera 等的代码
            xsltProcessor=新 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();
</脚本>    

于 2008-09-19T10:18:08.620 回答
0

以下是 XMLDocLoad 函数。

函数 XMLDocLoad(fname)
{
    var xmlDoc;

    如果(窗口。ActiveXObject){
        // IE代码
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async=false;
        xmlDoc.load(fname);

        返回(xmlDoc);
    }
    否则如果(document.implementation && document.implementation.createDocument){
        // Mozilla、Firefox、Opera 等的代码
        xmlDoc=document.implementation.createDocument("","",null);

        xmlDoc.async=false;
        xmlDoc.load(fname);

        返回(xmlDoc);

    }
    别的{
        alert('您的浏览器无法处理此脚本');
    }


}
于 2008-09-21T10:27:54.813 回答