首页 » XML » 跨浏览器处理XML

跨浏览器处理XML

很少有开发人员能够有福气专门针对一款浏览器做开发。因此,编写能够跨浏览器处理XML的函数就成了常见的需求。对解析XML而言,下面这个函数可以在所有四种主要浏览器中使用。

function parseXml(xml) {
    var xmldom = null;
    if (typeof DOMParser != "undefined") {
        xmldom = (new DOMParser()).parseFromString(xml, "text/xml");
        var errors = xmldom.getElementsByTagName("parsererror");
        if (errors.length) {
            throw new Error("XML 解析错误:" + errors[0].textContent);
        }
    } else if (typeof ActiveXObject != "undefined") {
        xmldom = createDocument();
        xmldom.loadXML(xml);
        if (xmldom.parseError != 0) {
            throw new Error("XML 解析错误:" + xmldom.parseError.reason);
        }
    } else {
        throw new Error("No XML 解析可用.");
    }

    return xmldom;
}

这个parseXml()函数只接收一个参数,即可解析的XML字符串。在函数内部,我们通过能力检测来确定要使用XML解析方式。DOMParser类型是受支持最多的解决方案,因此首先检测该类型是否有效。如果是,则创建一个新的DOMParser对象,并将解析XML字符串的结果保存在变量xmldom中。由于DOMParser对象在发生错误时不抛出错误(除IE9+之外),因此还要检测返回的文档以确定解析过程是否顺利。如果发生了解析错误,则根据错误消息抛出一个错误。

函数的最后一部分代码检测了对ActiveX的支持,并使用前面定义的createDocument()函数来创建适当版本的XML文档。与使用DOMParser时一样,这里也需要检测结果,以防有错误发生。如果确实有错误发生,同样也需要抛出一个包含错误原因的错误。

如果上述XML解析器都不可用,函数就会抛出一个错误,表示无法解析了。

在使用这个函数解析XML字符串时,应该将它放在try-catch语句当中,以防发生错误。来看下面的例子。

var xmldom = null;

try {
    xmldom = parseXml("<root><child/></root>");
} catch (ex) {
    alert(ex.message);
}

//进一步处理

对序列化XML而言,也可以按照同样的方式编写一个能够在四大浏览器中运行的函数。例如:

function serializeXml(xmldom) {
    if (typeof XMLSerializer != "undefind") {
        return (new XMLSerializer()).serializeToString(xmldom);
    } else if (typeof xmldom.xml != "undefined") {
        return xmldom.xml;
    } else {
        throw new Error("不能序列化的 XML DOM.");
    }
}

这个serializeXML()函数接收一个参数,既要序列化的XML DOM文档。与parseXml()函数一样,这个函数首先也是检测到最广泛支持的特性,即XMLSerializer。如果这个类型有效,则使用它来生成并返回文档的XML字符串。由于AcitveX方案比较简单,只使用了一个xml属性,因此这个函数直接检测了该属性。如果上述两个方面尝试都失败了,函数就会抛出一个错误,说明序列化不能进行。一般来说,只要针对浏览器使用了适当的XML DOM对象,就不会出现无法序列化的情况,因而也就没有必要在try-catch语句中调用serializeXml()。结果,就只需如下一行代码即可:

var xmldom = null;
try {
    xmldom = parseXml("<root><child/></root>");
} catch (ex) {
    alert(ex.message);
}

alert(serializeXml(xmldom));

只不过由于序列化过程的差异,相同的DOM对象在不同的浏览器下,有可能会得到不同的XML字符串。

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