JavaScript XML DOM 跨浏览器兼容处理指南
本文详细解析了 JavaScript 中 XML DOM 在不同浏览器下的实现差异,重点对比了 IE 基于 ActiveX 的 MSXML 库与 Mozilla 系列浏览器基于 DOMImplementation 和 DOMParser 的标准实现。文章提供了创建、加载、获取及错误处理的具体代码示例,并封装了一个兼容 IE 和 Firefox 的通用 XML DOM 接口,帮助开发者解决旧版浏览器环境下的 XML 解析兼容性问题。
IE 中的 XML DOM 支持
Internet Explorer 对 XML 的支持依赖于 ActiveX 技术中的 MSXML 组件库。
1、创建 XML DOM 对象
针对 MSXML 的不同版本,系统会生成对应的 XML DOM 对象实例,因此建议优先选用较新的 XML DOM 版本以确保兼容性。
2、加载 XML 数据
XML 数据的加载主要分为两种模式:
加载 XML 字符串:通过 loadXML 方法传入 XML 字符串参数。
加载 XML 文件:通过 load 方法指定文件路径。默认情况下,文件加载操作为异步执行;若需改为同步加载,可将 async 属性设置为 true。在异步加载文件时,需要监听 readyState 状态变化以及 onreadystatechange 事件处理函数。readyState 属性共有五种可能的状态值:
0——DOM 尚未初始化任何信息;
1——DOM 正在载入数据;
2——DOM 完成了数据载入;
3——DOM 已经可用,不过某些部分可能还不能用;
4——DOM 已经完全被载入,可以使用了。
3、获取 XML 字符串
微软为每个节点增加了 xml 特性,因此获取 XML 字符串非常方便,具体可见后续示例代码。
4、处理解析错误
可以使用 parseError 对象来处理在 XML 加载过程中出现的错误。
parseError 属性实际上是一个包含以下字段的对象:
errorCode:错误类型数字代码,没有错误时为 0;
filePos:错误发生在文件中的位置;
line:遇到错误的行号;
linepos:在遇到错误的那一行上的字符的位置;
reason:对错误的一个解释;
srcText:造成错误的代码片段;
url:造成错误的文件的 URL。
5、示例代码
代码如下:
function createXMLDOM(){
var arrSignatures=["MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument","Microsoft.XmlDom"];
for(var i=0;i<arrSignatures.length;i++){
try{
var oXmlDom=new ActiveXObject(arrSignatures[i]);
return oXmlDom;
} catch(oError){
}
}
throw new Error("MSXML is not installed on your system");
}
var oXmlDom=createXMLDOM();
//方式一:加载字符串
oXmlDom.loadXML("<root><child/></rot>");
//处理错误
if(oXmlDom.parseError != 0){
var oError=oXmlDom.parseError;
alert("An Error occurred:\nError Code:" + oError.errorCode
+ "\nLine:" + oError.line + "\nLine Pos:" + oError.linepos
+ "\nReason:" + oError.reason);
} else {
var childNodes=oXmlDom.documentElement.childNodes;
console.log(childNodes.length+" "+childNodes[0].xml);// 1 <child/>
}
//方式二:加载XML文件
oXmlDom.onreadystatechange = function(){
//文档加载完毕
if(oXmlDom.readyState == 4){
if(oXmlDom.parseError != 0){
var oError=oXmlDom.parseError;
alert("An Error occurred:\nError Code:" + oError.errorCode
+ "\nLine:" + oError.line + "\nLine Pos:" + oError.linepos
+ "\nReason:" + oError.reason);
} else {
var childNodes=oXmlDom.documentElement.childNodes;
console.log(childNodes.length+" "+childNodes[0].xml);// 1 <child/>
}
}
}
oXmlDom.load("test.xml"); 二、Mozilla 中的 XML DOM 支持
Mozilla 中的 XML DOM 支持
1、创建 DOM
DOM 标准指出,document.implementation 有一个 createDocument() 方法:
var oXmlDom=document.implementation.createDocument("","",null); 其中,第一个参数为文档的命名空间 URL,第二个参数为文档元素的标签名,第三个参数为文档类型对象(在 Mozilla 中通常始终为 null,因为尚未完全支持)。
2、加载 XML
Mozilla 浏览器只支持一种加载 XML 的方法:load(文件名)。
同步或异步由 async 属性决定,默认为异步模式。
如果是 XML 字符串,需要使用 DOMParser 对象将其转换为 DOM 对象,用法如下:
代码如下:
var oParser = new DOMParser();
var oXmlDom = oParser.parseFromString("<root/>","text/xml"); parseFromString 方法的第一个参数为 XML 字符串,第二个参数为内容类型,可以是 "text/xml" 或 "application/xml"。
3、获取 XML 字符串
微软提供的 xml 特性并非标准,因此 Mozilla 浏览器不支持该特性。Mozilla 提供了 XMLSerializer 对象来实现相同功能:
代码如下:
var oSerializer = new XMLSerializer();
var sXml = oSerializer.serializeToString(oXmlDom,"text/xml"); 在后面的例子中我们可以看到如何用 defineGetter() 方法来定义一个 xml 特性。 4、解析错误处理
在 XML 文件解析过程中发生错误时,XML DOM 会创建文档来解释这个错误。通常使用正则表达式来提取并输出错误信息:
代码如下:
var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+),Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
if(oXmlDom.documentElement.tagName == "parsererror"){
reError.test(oXmlDom.xml);
alert("An error occurred:\nDescription: " + RegExp.$1 +"\n"
+ "File: " + RegExp.$2 + "\n"
+ "Line: " + RegExp.$3 + "\n"
+ "Line Pos: " + RegExp.$4 + "\n"
+ "Source: " + RegExp.$5);
} 5、示例代码
代码如下:
var oXmlDom=document.implementation.createDocument("","<root>",null);
oXmlDom.async = false;
oXmlDom.onload = function(){
alert('Done');
}
var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+),Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
if(oXmlDom.documentElement.tagName == "parsererror"){
reError.test(oXmlDom.xml);
alert("An error occurred:\nDescription: " + RegExp.$1 +"\n"
+ "File: " + RegExp.$2 + "\n"
+ "Line: " + RegExp.$3 + "\n"
+ "Line Pos: " + RegExp.$4 + "\n"
+ "Source: " + RegExp.$5);
}
Node.prototype.__defineGetter__("xml", function () {
var oSerializer = new XMLSerializer();
return oSerializer.serializeToString(this, "text/xml");
});
oXmlDom.load('test.xml');
alert(oXmldom.xml);
var oNode = oXmlDom.documentElement.childNodes[1];
alert(oNode.xml); 三、通用接口
通用接口实现
下面是兼容 IE 和 FireFox 的通用接口实现:
代码如下:
function XmlDom() {
if (window.ActiveXObject) {//IE
var arrSignatures = ["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0",
"MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument", "Microsoft.XmlDom"];
for (var i = 0; i < arrSignatures.length; i++) {
try {
var oXmlDom = new ActiveXObject(arrSignatures[i]);
return oXmlDom;
}
catch (oError) {
//ignore
}
}
throw new Error("MSXML is not installed on your system.");
} else if (document.implementation && document.implementation.createDocument) {
var oXmlDom = document.implementation.createDocument("", "", null);
oXmlDom.parseError = {valueOf:function () {
return this.errorCode;
}, toString:function () {
return this.errorCode.toString();
}};
oXmlDom.__initError__();
oXmlDom.addEventListener("load", function () {
this.__checkForErrors__();
this.__changeReadyState__(4);
}, false);
return oXmlDom;
} else {
throw new Error("Your browser doesn't support an XML DOM object.");
}
}
if (isMoz) {
Document.prototype._readyState_ = 0;
Document.prototype.onreadystatechange = null;
Document.prototype.__changeReadyState__ = function (iReadyState) {
this._readyState_ = iReadyState;
if (typeof this.onreadystatechange == "function") {
this.onreadystatechange();
}
};
Document.prototype.__initError__ = function () {
this.parseError.errorCode = 0;
this.parseError.filepos = -1;
this.parseError.line = -1;
this.parseError.linepos = -1;
this.parseError.reason = null;
this.parseError.srcText = null;
this.parseError.url = null;
};
Document.prototype.__checkForErrors__ = function () {
if (this.documentElement.tagName == "parsererror") {
var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+),Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
reError.test(this.xml);
this.parseError.errorCode = -999999;
this.parseError.reason = RegExp.$1;
this.parseError.url = RegExp.$2;
this.parseError.line = parseInt(RegExp.$3);
this.parseError.linepos = parseInt(RegExp.$4);
this.parseError.srcText = RegExp.$5;
}
};
Document.prototype.loadXML = function (sXml) {
this.__initError__();
this.__changeReadyState__(1);
var oParser = new DOMParser();
var oXmlDom = oParser.parseFromString(sXml, "text/xml");
while (this.firstChild) {
this.removeChild(this.firstChild);
}
for (var i = 0; i < oXmlDom.childNodes.length; i++) {
var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
this.appendChild(oNewNode);
}
this.__checkForErrors__();
this.__changeReadyState__(4);
};
Document.prototype.__load__ = Document.prototype.load;
Document.prototype.load = function (sURL) {
this.__initError__();
this.__changeReadyState__(1);
this.__load__(sURL);
};
Document.prototype.getReadyState = function () {
return this._readyState_;
};
Node.prototype.__defineGetter__("xml", function () {
var oSerializer = new XMLSerializer();
return oSerializer.serializeToString(this, "text/xml");
});
} 四、其他浏览器
其他浏览器处理
本书中没有讲到其他浏览器,如现在很火的 Chrome,最新版的主流浏览器现在都已支持上面讲到的 Mozilla 方式。如果不支持,可以用 AJAX 来读取处理 XML。
作者:Artwl
出处:http://artwl.cnblogs.com
JavaScript零基础入门:从环境搭建到运行第一段代码
2026-11-05 15:29:58
HTML链接中javascript:void(0)的作用及现代替代方案
2026-11-05 10:07:47
在线调试 JS 时怎么引入 jQuery 或 Vue 等第三方库
2026-11-05 08:53:56
原生JavaScript实现简易颜色选择器原理与代码
2026-11-03 23:22:19
JS原生表单序列化:FormData与URLSearchParams用法详解
2026-11-03 23:13:21
