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 相关文章推荐
JS模拟的QQ面板上的多级可展开的菜单
Oct 10 Javascript
JQuery的一些小应用收集
Mar 27 Javascript
jquery插件splitScren实现页面分屏切换模板特效
Jun 16 Javascript
Javascript的表单验证长度
Mar 16 Javascript
jQuery遍历DOM元素与节点方法详解
Apr 14 Javascript
底部悬浮通栏可以关闭广告位的实现方法
Jun 01 Javascript
js正则表达式验证表单【完整版】
Mar 06 Javascript
AngularJS使用ui-route实现多层嵌套路由的示例
Jan 10 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
Aug 22 Javascript
PM2自动部署代码步骤流程总结
Dec 10 Javascript
基于Three.js实现360度全景图片
Dec 30 Javascript
浅谈webpack构建工具配置和常用插件总结
May 11 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
谏山创故乡大分县日田市水坝将设立《进击的巨人》立艾伦、三笠以及阿尔敏的铜像!
2020/03/06 日漫
PHP n个不重复的随机数生成代码
2009/06/23 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
js 调整select 位置的函数
2008/02/21 Javascript
23个超流行的jQuery相册插件整理分享
2011/04/25 Javascript
jQuery的slideToggle方法实例
2013/05/07 Javascript
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
jQuery选择器源码解读(三):tokenize方法
2015/03/31 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
原生js实现放大镜效果
2017/01/11 Javascript
Vue插件写、用详解(附demo)
2017/03/20 Javascript
JavaScript中附件预览功能实现详解(推荐)
2017/08/15 Javascript
微信小程序自定义toast的实现代码
2018/11/16 Javascript
vue实现歌手列表字母排序下拉滚动条侧栏排序实时更新
2019/05/14 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
JavaScript实现PC端四格密码输入框功能
2020/02/19 Javascript
mapboxgl区划标签避让不遮盖实现的代码详解
2020/07/01 Javascript
javascript实现打砖块小游戏(附完整源码)
2020/09/18 Javascript
python操作日期和时间的方法
2014/03/11 Python
Python实现Smtplib发送带有各种附件的邮件实例
2017/06/05 Python
python 判断是否为正小数和正整数的实例
2017/07/23 Python
Python3.5基础之函数的定义与使用实例详解【参数、作用域、递归、重载等】
2019/04/26 Python
Python代码太长换行的实现
2019/07/05 Python
Python实现一个数组除以一个数的例子
2019/07/20 Python
使用python模拟高斯分布例子
2019/12/09 Python
使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)
2020/10/12 Python
Python类class参数self原理解析
2020/11/19 Python
CSS3 Calc实现滚动条出现页面不跳动问题
2017/09/14 HTML / CSS
详解HTML5布局和HTML5标签
2020/10/26 HTML / CSS
PUMA官方商城:世界领先的运动品牌之一
2016/11/16 全球购物
乡村文明行动实施方案
2014/03/29 职场文书
反对邪教标语
2014/06/30 职场文书
大学生团日活动总结
2015/05/06 职场文书
2015年度绩效考核工作总结
2015/05/27 职场文书
扩展多台相同的Web服务器
2021/04/01 Servers
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫