JavaScript高級(jí)程序設(shè)計(jì) 閱讀筆記(二十一) JavaScript中的XML
IE對(duì)XML的支持是基于ActiveX的MSXML庫(kù)。
1、DOM創(chuàng)建
對(duì)每個(gè)新版本的MSXML,都會(huì)創(chuàng)建出不同的XML DOM對(duì)象,所以盡量選擇新的XML DOM版本。
2、載入XML
載入XML分兩種,即:
載入XML字符串:loadXML(xml字符串)
載入xml文件:load(xml文件路徑)。默認(rèn)情況下文件載入是異步的,如果要改為同步把a(bǔ)synce特性改為true即可。異步載入文件時(shí)要用到readyState和onreadystatechange事件處理函數(shù)。readyState共有五種可能的值:
0——DOM尚未初始化任何信息;
1——DOM正在載入數(shù)據(jù);
2——DOM完成了數(shù)據(jù)載入;
3——DOM已經(jīng)可用,不過(guò)某些部分可能還不能用;
4——DOM已經(jīng)完全被載入,可以使用了。
3、獲取XML
微軟為每個(gè)節(jié)點(diǎn)增加了xml特性,所以獲取XML非常方便,見(jiàn)后面的示例。
4、解釋錯(cuò)誤
可以用parseError來(lái)處理XML載入過(guò)程中出現(xiàn)的錯(cuò)誤。
parseError特性實(shí)際上是包含以下特性的對(duì)象:
errorCode:錯(cuò)誤類(lèi)型數(shù)字代碼,沒(méi)有錯(cuò)誤為0
filePos:錯(cuò)誤發(fā)生在文件中的位置
line:遇到錯(cuò)誤的行號(hào)
linepos:在遇到錯(cuò)誤的那一行上的字符的位置
reason:對(duì)錯(cuò)誤的一個(gè)解釋
srcText:造成錯(cuò)誤的代碼
url:造成錯(cuò)誤的文件的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>");
//處理錯(cuò)誤
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、創(chuàng)建DOM
DOM標(biāo)準(zhǔn)指出,document.implementation有個(gè) createDocument() 方法:
var oXmlDom=document.implementation.createDocument("","",null); 其中,第一個(gè)參數(shù)為文檔的命名空間URL,文檔元素的標(biāo)簽名,和文檔類(lèi)型對(duì)象(總是為null,因?yàn)樵贛ozilla中還沒(méi)有支持)。
2、載入XML
Mozilla只支持一個(gè)載入XML的方法:load(文件名)。
同步或異步由async決定,默認(rèn)為異步。
如果是XML字符串,要用DOMParser對(duì)象來(lái)轉(zhuǎn)換成DOM,用法如下:
var oParser = new DOMParser();
var oXmlDom = oParser.parseFromString("<root/>","text/xml");
parseFromString方法第一個(gè)參數(shù)為XML字符串,第二個(gè)參數(shù)為內(nèi)容類(lèi)型??梢允?"text/xml" 或 "application/xml"。
3、獲取XML
微軟提供的xml特性因?yàn)椴皇菢?biāo)準(zhǔn),所以Mozilla不支持,Mozilla提供了XMLSerializer對(duì)象:
var oSerializer = new XMLSerializer();
var sXml = oSerializer.serializeToString(oXmlDom,"text/xml"); 在后面的例子中我們可以看到如何用defineGetter()方法來(lái)定義一個(gè)xml特性。
4、解析錯(cuò)誤
在XML文件的解析過(guò)程中發(fā)生錯(cuò)誤時(shí),XML DOM會(huì)創(chuàng)建文檔來(lái)解釋這個(gè)錯(cuò)誤。常常用正則來(lái)輸出錯(cuò)誤信息:
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");
});
}
四、其他瀏覽器
本書(shū)中沒(méi)有講到其他瀏覽器,如現(xiàn)在很火的Chrome,最新版的主流瀏覽器現(xiàn)在都已支持上面講到的Mozilla方式。如果不支持,可以用AJAX來(lái)讀取處理XML。
作者:Artwl
出處:http://artwl.cnblogs.com
- javascript解析xml字符串的函數(shù)
- JavaScript 解析讀取XML文檔 實(shí)例代碼
- javascript 讀取XML數(shù)據(jù),在頁(yè)面中展現(xiàn)、編輯、保存的實(shí)現(xiàn)
- javascript XMLHttpRequest對(duì)象全面剖析
- Javascript(AJAX)解析XML的代碼(兼容FIREFOX/IE)
- javascript操作xml(增刪改查)例子代碼hta版
- JavaScript XML和string相互轉(zhuǎn)化實(shí)現(xiàn)代碼
- JavaScript高級(jí)程序設(shè)計(jì) XML、Ajax 學(xué)習(xí)筆記
- JavaScript操作XML 使用百度RSS作為新聞源示例
- javascript+xml實(shí)現(xiàn)簡(jiǎn)單圖片輪換(只支持IE)
- 如何使用Javascript正則表達(dá)式來(lái)格式化XML內(nèi)容
- javascript讀取Xml文件做一個(gè)二級(jí)聯(lián)動(dòng)菜單示例
- 兼容Firefox的Javascript XSLT 處理XML文件
相關(guān)文章
基于Bootstrap 3 JQuery及RegExp的表單驗(yàn)證功能
這篇文章主要介紹了基于Bootstrap 3 JQuery及RegExp的表單驗(yàn)證功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
微信小程序如何實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)功能詳解
這篇文章主要給大家介紹了關(guān)于微信小程序如何實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)功能的相關(guān)資料,包括頁(yè)面跳轉(zhuǎn)的方式、跳轉(zhuǎn)傳參的方法以及頁(yè)面返回的操作,通過(guò)簡(jiǎn)單的代碼示例,幫助讀者快速掌握微信小程序頁(yè)面跳轉(zhuǎn)的基本用法,下面需要的朋友可以參考下2023-03-03
JavaScript如何將時(shí)間戳轉(zhuǎn)化為年月日時(shí)分秒格式
這篇文章主要給大家介紹了關(guān)于JavaScript如何將時(shí)間戳轉(zhuǎn)化為年月日時(shí)分秒格式的相關(guān)資料,在前端的日常工作當(dāng)中,時(shí)間戳的使用也是不少的,有時(shí)后端返回給我們的數(shù)據(jù)是一個(gè)時(shí)間戳,我們需要轉(zhuǎn)換成年月日,時(shí)分秒的形式展示在頁(yè)面當(dāng)中,需要的朋友可以參考下2023-11-11
Javascript this 的一些學(xué)習(xí)總結(jié)
相信有C++、C#或Java等編程經(jīng)驗(yàn)的各位,對(duì)于this關(guān)鍵字再熟悉不過(guò)了。由于Javascript是一種面向?qū)ο蟮木幊陶Z(yǔ)言,它和C++、C#或Java一樣都包含this關(guān)鍵字,接下來(lái)我們將向大家介紹Javascript中的this關(guān)鍵字2012-08-08
關(guān)于javascript中this關(guān)鍵字(翻譯+自我理解)
在傳統(tǒng)面向?qū)ο笳Z(yǔ)言中,this關(guān)鍵字是個(gè)很乖的小孩,從不亂跑,該是誰(shuí)的就是誰(shuí)的。可是在JavaScript中,我們發(fā)現(xiàn)它不那么乖,有時(shí)甚至把我們搞的暈頭轉(zhuǎn)向的。所以有必要對(duì)它稍微做個(gè)總結(jié)。2010-10-10
JS實(shí)現(xiàn)課堂隨機(jī)點(diǎn)名和順序點(diǎn)名
這篇文章主要介紹了基于JS實(shí)現(xiàn)課堂隨機(jī)點(diǎn)名和順序點(diǎn)名的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-03-03
JavaScript+html5 canvas繪制漸變區(qū)域完整實(shí)例
這篇文章主要介紹了JavaScript+html5 canvas繪制漸變區(qū)域的方法,結(jié)合完整實(shí)例形式分析了canvas顏色調(diào)用與圖形繪制的相關(guān)技巧,需要的朋友可以參考下2016-01-01
JS 輸入字?jǐn)?shù)判斷實(shí)現(xiàn)代碼
判斷輸入的字?jǐn)?shù)2009-08-08
詳解如何編寫(xiě)一個(gè)Typescript的類(lèi)型聲明文件
我們知道TypeScript根據(jù)類(lèi)型聲明進(jìn)行類(lèi)型檢查,但有些情況可能沒(méi)有類(lèi)型聲明,這個(gè)時(shí)候就需要我們自己寫(xiě)一個(gè),下面小編就來(lái)和大家聊聊如果寫(xiě)一個(gè)Typescript的類(lèi)型聲明文件呢2023-06-06

