JavaScript高级程序设计 阅读笔记(二十一) JavaScript中的XML


Posted in Javascript onSeptember 14, 2012

一、IE中的XML DOM支持

IE对XML的支持是基于ActiveX的MSXML库。

1、DOM创建

对每个新版本的MSXML,都会创建出不同的XML DOM对象,所以尽量选择新的XML DOM版本。

2、载入XML

载入XML分两种,即:

载入XML字符串:loadXML(xml字符串)

载入xml文件:load(xml文件路径)。默认情况下文件载入是异步的,如果要改为同步把asynce特性改为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支持

1、创建DOM

DOM标准指出,document.implementation有个 createDocument() 方法:
var oXmlDom=document.implementation.createDocument("","",null);

其中,第一个参数为文档的命名空间URL,文档元素的标签名,和文档类型对象(总是为null,因为在Mozilla中还没有支持)。

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 相关文章推荐
jquery tab插件精简版分享
Sep 10 Javascript
jquery焦点图片切换(数字标注/手动/自动播放/横向滚动)
Jan 24 Javascript
Js 去掉字符串中的空格(实现代码)
Nov 19 Javascript
Javascript MVC框架Backbone.js详解
Sep 18 Javascript
使用javascript实现Iframe自适应高度
Dec 24 Javascript
JQuery CheckBox(复选框)操作方法汇总
Apr 15 Javascript
js实现选中复选框文字变色的方法
Aug 14 Javascript
js实现开启密码大写提示
Dec 21 Javascript
详解Angular的数据显示优化处理
Dec 26 Javascript
vue项目中用cdn优化的方法
Jan 03 Javascript
Bootstrap Paginator+PageHelper实现分页效果
Dec 29 Javascript
Vue为什么要谨慎使用$attrs与$listeners
Aug 27 Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
Sep 14 #Javascript
javascript时区函数介绍
Sep 14 #Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
Sep 14 #Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
Sep 14 #Javascript
基于JQuery的一句话搞定手风琴菜单
Sep 14 #Javascript
JQuery select控件的相关操作实现代码
Sep 14 #Javascript
11个用于提高排版水平的基于jquery的文字效果插件
Sep 14 #Javascript
You might like
php加密算法之实现可逆加密算法和解密分享
2014/01/21 PHP
php格式化日期实例分析
2014/11/12 PHP
return false;和e.preventDefault();的区别
2010/07/11 Javascript
js监听滚动条滚动事件使得某个标签内容始终位于同一位置
2014/01/24 Javascript
jquery的幻灯片图片切换效果代码分享
2015/09/07 Javascript
网页从弹窗页面单选框传值至父页面代码分享
2015/09/29 Javascript
jQuery prototype冲突的2种解决方法(附demo示例下载)
2016/01/21 Javascript
深入理解$.each和$(selector).each
2016/05/15 Javascript
手机Web APP如何实现分享多平台功能
2016/08/19 Javascript
[原创]javascript typeof id==='string'?document.getElementById(id):id解释
2016/11/02 Javascript
JavaScript原型继承_动力节点Java学院整理
2017/06/30 Javascript
JavaScript实现简单生成随机颜色的方法
2017/09/21 Javascript
100行代码实现vue表单校验功能(小白自编)
2019/11/19 Javascript
js刷新页面location.reload()用法详解
2019/12/09 Javascript
iSlider手机端图片滑动切换插件使用详解
2019/12/24 Javascript
javascript设计模式 ? 建造者模式原理与应用实例分析
2020/04/10 Javascript
js瀑布流布局的实现
2020/06/28 Javascript
理解python正则表达式
2016/01/15 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
2018/12/04 Python
Python反爬虫技术之防止IP地址被封杀的讲解
2019/01/09 Python
浅谈django2.0 ForeignKey参数的变化
2019/08/06 Python
pygame实现贪吃蛇游戏(下)
2019/10/29 Python
python实现布隆过滤器及原理解析
2019/12/08 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
2019/12/19 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
2020/09/01 Python
Android面试题附答案
2014/12/08 面试题
工程造价专业大学生自荐信
2013/10/01 职场文书
大学四年个人的自我评价
2014/02/26 职场文书
乐观自信演讲稿范文
2014/05/21 职场文书
书法兴趣小组活动总结
2014/07/07 职场文书
收银员岗位职责范本
2015/04/07 职场文书
2015年房产销售工作总结范文
2015/05/22 职场文书
幼儿园六一儿童节主持词
2015/06/30 职场文书
2016开学第一课心得体会
2016/01/23 职场文书
Golang中interface{}转为数组的操作
2021/04/30 Golang
总结三种用 Python 作为小程序后端的方式
2022/05/02 Python