首页 » XML » IE8及之前版本中的XML

IE8及之前版本中的XML

事实上,IE是第一个原生支持XML的浏览器,而这一支持是通过ActiveX对象实现的。为了便于桌面应用程序开发人员处理XML,微软创建了MSXML库;但微软并没有针对JavaScript创建不同的对象,而只是让Web开发人员能够通过浏览器访问相同的对象。

通过AtiveXObject类型可以在JavaScript中创建ActiveX对象的实例。同样,要创建一个XML文档的实例,也要使用ActiveXObject构造函数并为其传入一个表示XML文档版本的字符串。有6种不同的XML文档版本可以供选择。

  • Microsoft.XmlDom:最初随IE发布:不建议使用。
  • MSXML2.DOMDocument:为了方便脚本处理而更新的版本,建议仅在特殊情况下作为后备版本使用。
  • MSXML2.DOMDocument.3.0:为了在JavaScript中使用,这是最低的建议版本。
  • MSXML2.DOMDocument.4.0:在通过脚本处理时并不可靠,使用这个版本可能导致安全警告。
  • MSXML2.DOMDocument.5.0:在通过脚本处理时并不可靠,使用这个版本同样可能导致安全警告。
  • MSXML2.DOMDocument.6.0:通过脚本能够可靠处理的最新版本。

在这6个版本中,微软只推荐使用MSXML2.DOMDocument.6.0或MSXML2.DOMDocument.3.0;前者是最新最可靠的版本,而后者则是大多数Windows操作系统都支持的版本。可以使用后备版本的MSXML2.DOMDocument,仅在针对IE5.5之前的浏览器开发时才有必要使用。

通过尝试创建每个版本的实例并观察是否有错误发生,可以确定那个版本可用。例如:

function createDocument() {
    if (typeof arguments.callee.activeXString != "string") {
        var versions = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument"],
            i, len;
        for (i = 0, len = versions.length; i < len; i++) {
            try {
                var xmldom = new ActiveXObject(versions[i]);
                arguments.callee.activeXString = versions[i];
                break;
            } catch (ex) {
                //跳过
            }
        }
    }
    return new ActiveXObject(arguments.callee.activeXString);
}

这个函数中使用for循环迭代了每个可能的ActiveX版本。如果版本无效,则创建新ActiveXObect的调用就会抛出错误;此时,catch语句就会捕获错误,循环继续。如果没有发生错误,则可用的版本将被保存在这个函数的activeXString属性中。这样,就不必在每次调用这个函数时都重复检查可用版本了——直接创建并返回对象即可。

要解析XML字符串,首先必须创建一个DOM文档,然后调用loadXML()方法。新创建的XML文档完全是一个空文档,因而不能对其进行任何操作。为loadXML()方法传入的XML字符串经过解析之后会被填充到DOM文档中。来看下面的例子。

var xmldom = createDocument();
xmldom.loadXML("<root><child/></root>");

alert(xmldom.documentElement.tagName); //"root"
alert(xmldom.documentElement.firstChild.tagName); //"child"

var anotherChild = xmldom.createElement("child");
xmldom.documentElement.appendChild(anotherChild);

var children = xmldom.getElementsByTagName("child");
alert(children.length); //2
alert(xmldom.xml);

在新DOM文档中填充了xml内容之后,就可以像操作其它DOM文档一样操作它了(可以使用任何方法和属性)。

如果解析过程中出错,可以在parseError属性中找到错误的信息。这个属性本身就是一个包含多个属性的对象,每个属性都保存着有关解析错误的某一方面信息。

  • errorCode:错误类型的的数值编码:在没有发生错误时值为0。
  • filePos:文件总导致错误发生的位置。
  • line:发生错误的行。
  • linepos:发生错误的行。
  • reason:对错误的文本解释。
  • srcText:导致错误的代码。
  • url:导致错误的文件URL(如果有这个文件的话)。

另外,parseError的valueOf()方法返回errorCode的值,因此可以通过下列代码检测是否发生了错误解析。

var xmldom = createDocument();
xmldom.loadXML("<root>");

if (xmldom.parseError != 0) {
    alert("解析发生错误.");
}

错误类型的数值编码可能是正值,也可能是负值,因此我们只需检测它是不是等于0。要取得有关解析错误的详细信息也很容易,而且可以将这些信息组合起来给出更有价值的解释。来看下面的例子。

var xmldom = createDocument();
xmldom.loadXML("<root>");

if (xmldom.parseError != 0) {
    alert("发生一个错误:\n错误代码:" + xmldom.parseError.errorCode + "\n" + "行 :" + xmldom.parseError.line + "\n" + "原因: " + xmldom.parseError.reason);
}

应该在调用loadXML()之后、查询XML文档之前,检查是否发生了解析错误。

1.序列化XML

IE将序列化XML的能力内置在了DOM文档中。每个DOM节点都有一个XML属性,其中保存着表示该节点的XML字符串。例如:

alert(xmldom.xml);

文档中的每个节点都支持这个简单的序列化机制,无论是序列化整个文档还是某个子文档树,都非常方便。

2.加载XML文件

IE中的XML文档对象也可以加载来自服务器的文件。与DOM3级中的功能类似,要加载的XML文档必须与页面中运行的JavaScript代码来自同一台服务器。同样与DOM3级规范类似,加载文档的方式也可以分为同步和异步两种。要指定加载文档的方式,可以设置async属性,true表示异步,false表示同步(默认值为true)。来看下面的例子:

var xmldom = createDocument();
xmldom.async = flase;

在确定了加载XML文档的方式后,调用load()可以启动下载过程。这个方法接受一个参数,既要加载的XML文件的URL。在同步方式下,调用load()可以立即检测解析错误并立即执行相关的XML处理,例如:

var xmldom = createDocument();
xmldom.async = false;
xmldom.load("example.xml");

if (xmldom.parseError != 0) {
    //处理错误
} else {
    alert(xmldom.documentElement.tagName); //"root"
    alert(xmldom.documentElement.firstChild.tagName); //"child"

    var anotherChild = xmldom.createElement("child");
    xmldom.documentElement.appendChild(anotherChild);

    var children = xmldom.getElementsByTagName("child");
    alert(children.length); //2

    alert(xmldom.xml);
}

由于是以同步方式处理XML文件,因此在解析完成之前,代码不会继续执行,这样的编程工作要简单一点。虽然同步方式比较方便,但如果下载时间太长,会导致程序反映很慢。因此,在加载XML文档时,通常都使用异步方式。

在异步加载XML文件的情况下,需要为XML DOM文档的onreadystatechange事件指定处理程序。有4个就绪状态(ready state).

  • 1:DOM正在加载数据
  • 2:DOM已经加载完数据。
  • 3:DOM已经使用,但某些部分可能还无法访问。
  • 4:DOM已经可以使用。

在实际开发中,要关注的只有一个就绪状态:4。这个状态表示XML文件已经全部加载完毕,而且已经全部解析为DOM文档。通过XML文档的readyState属性可以取得其就绪状态。以异步方式加载XMl文件的典型模式如下。

var xmldom = createDocument();
xmldom.async = true;

xmldom.onreadystatechange = function () {
    if (xmldom.readyState == 4) {
        if (xmldom.parseError != 0) {
            alert("发生一个错误:\n错误代码:" + xmldom.parseError.errorCode + "\n" + "行 :" + xmldom.parseError.line + "\n" + "原因: " + xmldom.parseError.reason);
        } else {
            alert(xmldom.documentElement.tagName); //"root"
            alert(xmldom.documentElement.firstChild.tagName); //"child"

            var anotherChild = xmldom.createElement("child");
            xmldom.documentElement.appendChild(anotherChild);

            var children = xmldom.getElementsByTagName("child");
            alert(children.length); //2

            alert(xmldom.xml);
        }
    }
};

xmldom.load("example.xml");

要注意的是,为onreadystatecahnge事件指定处理程序的语句,必须放在调用load()方法的语句之前;这样,才能确保在就绪状态变化时调用该事件处理程序。另外,在事件处理程序内部,还必须注意要使用XML文档变量的名称(xmldom),不能使用this对象。原因是ActiveX控件为预防安全问题不允许使用this对象。文档的就绪状态变化为4时,就可以放心地检测是否发生了解析错误,并在未发生错误的情况下处理XML。

虽然可以通过XML DOM文档加载XML文件,但公认的还是使用XMLHttpRequest对象比较好。

此文章发表在 XML. 将 固定链接 加入收藏.