在IE中处理XSL片段

XSL processing a fragment in IE

本文关键字:XSL 片段 处理 IE      更新时间:2023-09-26

我正在尝试使用Javascript将XML文件的一部分转换为HTML表的单行。我的想法是,我将从多个XML文件在表中创建多个行。对于Firefox和Opera,这一小段代码运行得非常好。

var resTable = document.createElement('table');
for (i = 0; i < xmlNames.length; i++)
{
  // code for IE
  if (window.ActiveXObject)
  {
  }
  // code for Mozilla, Firefox, Opera, etc.
  else if (document.implementation && document.implementation.createDocument)
  {
    xml=loadXMLDoc(xmlNames[i]);
    xsl=loadXMLDoc(xslName);
    xsltProcessor=new XSLTProcessor();
    xsltProcessor.importStylesheet(xsl);
    resultDocument = xsltProcessor.transformToFragment(xml,document);
    resTable.appendChild(resultDocument);
  }
}
document.getElementById("theDoc").appendChild(resTable);

问题是,我在"if IE"部分尝试了一千种方法,但没有一种方法有效。在我问之前,我已经做了很多谷歌搜索和浏览,但无济于事。事实上,关于SO有一个未回答的问题,听起来很相似,但是没有回应也没有解决方案,所以我希望有人能在这里帮助我。

我已经成功地让整个文档在IE上转换,但事实是,我想这样做作为一个片段是什么导致我的问题。任何帮助将非常感激!谢谢!

编辑:对不起,我忘了提供我的loadXMLDoc功能,以防这很重要。这是:

function loadXMLDoc(dname)
{
  if (window.XMLHttpRequest)
  {
    xhttp=new XMLHttpRequest();
  }
  else
  {
    xhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xhttp.open("GET",dname,false);
  xhttp.send("");
  return xhttp.responseXML;
}

经过多次尝试和错误,我想出了一些有效的方法。我是这样做的:

像往常一样创建一个xsltProcessor,并调用transform方法。这就产生了xsltProcessor。输出为HTML格式的字符串。当然,我需要一个DOM元素,所以我必须将HTML字符串转换为DOM。幸运的是,因为我也是XSL样式表的作者,所以我确切地知道我期望得到什么。在我的例子中,输出的HTML字符串将是若干…元素。我最初尝试将我的resTable(一个表DOM元素)innerHTML设置为输出字符串,但这不起作用。我仍然不知道为什么,但它似乎有一些具体的事实,他们是s,它不能被解析时设置为innerHTML表标签的上下文之外。

无论如何,我创建了一个临时div元素,并将其innerHTML设置为一个字符串,其中xsltProcessor的输出字符串包含在

标记中。现在,临时div元素是一个DOM表,然后我对它进行遍历并获取子节点(它们是xsl处理器首先返回的tr节点)。这样做似乎有点荒谬,但它很有效,这是我第一次可以说……这是在我测试过的所有浏览器上都能运行的最终版本。
var resTable = document.createElement('table');
for (i = 0; i < xmlNames.length; i++)
{
  // code for IE
  if (window.ActiveXObject)
  {
    var xml = new ActiveXObject("Microsoft.XMLDOM");
    xml.async = false;
    xml.load(xmlNames[i]);
    var xslt = new ActiveXObject("Msxml2.XSLTemplate");
    var xsl = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.3.0");
    var xsltProcessor;
    xsl.async = false;
    xsl.resolveExternals = false;
    xsl.load(xslName);
    xslt.stylesheet = xsl;
    xsltProcessor = xslt.createProcessor();
    xsltProcessor.input = xml;
    //This transform results in one or more tr.../tr HTML tag(s)
    xsltProcessor.transform();
    //Create a temp div element which is used to convert the HTML
    //string to a DOM element so I can grab just the part I want..
    tmp = document.createElement('div');
    //Can't set innerHTML to tr tags directly I guess, so have to put
    //in context of a table so it can be parsed...
    tmp.innerHTML = "<table>" + xsltProcessor.output + "</table>";
    //Now I need to grad the tr children from inside the table node, since
    //the table was only to please the parser
    for (tmpChildInd = 0; tmpChildInd <  tmp.childNodes[0].childNodes.length;   tmpChildInd++)
    {
      //finally, append the temporary elements children (the tr tags) 
      //to the overall table I created before the loop.
      resTable.appendChild(tmp.childNodes[0].childNodes[tmpChildInd]);
    }  
  }
  // code for Mozilla, Firefox, Opera, etc.
  else if (document.implementation && document.implementation.createDocument)
  {
    xml=loadXMLDoc(xmlNames[i]);
    xsl=loadXMLDoc(xslName);
    xsltProcessor=new XSLTProcessor();
    xsltProcessor.importStylesheet(xsl);
    resultDocument = xsltProcessor.transformToFragment(xml,document);
    resTable.appendChild(resultDocument);
  }
}
//put the full table at the div location "theDoc" now..
document.getElementById("theDoc").appendChild(resTable);

不知道有多少人尝试这样做,但希望这对其他人有所帮助。