js xmldom

一. 瀏覽器中的XML DOM支持
目前只有兩種瀏覽器支持客戶端的XML處理,分別是IE和Mozilla。
1. IE中的XML DOM支持
在爲IE添加XML支持時,微軟在JavaScript之外另尋了個方案:基於ActiveX的MSXML庫。
1) DOM創建
對每個新版本的MSXML,都會創建出不同的XML DOM對象,而它們各自的名稱也不相同,MSXML最新的版本是5.0。它存在如下幾種XML DOM實現:
i)Microsoft XmlDom(最原始的);
ii)MSXML2.DOMDocument;
iii)MSXML2.DOMDocument3.0;
iv)MSXML2.DOMDocument4.0;
v)MSXML2.DOMDocument5.0。
爲確保使用了正確的XML DOM版本,也爲避免任何其他錯誤,我們可以創建一個函數來測試每個XML DOM對象字符串,出現錯誤即捕獲:function
createXMLDOM() {
var arrSignatures = {"MSXML2.DOMDocument5.0", "MSXML2.DOMDocument4.0", "MSXML2.DOMDocument3.0", "MSXML2.DOMDocument",
"Microsoft XmlDom"};
for (var i= 0; i < arrSignatures.length; i++) {
try {
var oXmlDom = new ActiveXObject(arrSignatures);
return oXmlDom;
} catch(oError) {
//ignore
}
}
throw new Error("SXML is not installed on your system.";
}

注意:這段在IE中創建XML DOM的代碼在其他瀏覽器會出現錯誤。因此,必須在其之前先進行瀏覽器檢測。
2) 載入XML
有了可用的XML DOM對象後,就可以載入XML了,微軟的XML DOM提供兩種方法,.即:loadXML()和load()。
loadXML()方法可直接向XML DOM輸入XML字符串,eg.
var oXmlDom = createXMLDOM();
oXmlDom.loadXML("<root><child/></root>");
load()方法用於從服務器上載入XML文件,不過load()方法只可以載入與包含JavaScript的頁面存儲於同一個服務器上的文件,即:不可以通過其他人
的服務器載入XML文件。
還有兩種載入文件的模式:同步與異步。以同步模式載入時,JavaScript代碼會等待文件完全載入後才繼續執行代碼;而以一步模式載入時,不會等
待,可以使用事件處理函數來判斷文件是否完全載入了。默認情況下,爲異步載入。要進行同步載入,需設置async特性爲false,如下:
oXmlDom. async = false;
然後使用load()方法,並給出要載入的文件名:
oXmlDom.load("test.xml");
異步載入文件時,要使用readyState特性和onreadystatechange事件處理函數:
readyState特性有五種可能的值:
0--DOM尚未初始化任何信息;
1--DOM尚未載入數據;
2--DOM完成了數據載入;
3--DOM已經可用,不過某些部分可能還不能用;
4--DOM已經完全被載入,可以使用了。
一旦readyState的值發生變化,就會觸發onreadystatechange事件。使用該函數,就可以在DOM完全載入時,發出通知:
oXmlDom.onreadystatechange = function() {
if (oXmlDom.readyState == 4) {
alert("已完全載入!");
}
}
必須在調用load()方法前分配好onreadystatechange事件處理函數,如下所示:
oXmlDom.onreadystatechange = function() {
if (oXmlDom.readyState == 4) {
alert("已完全載入!");
}
}
oXmlDom.load("test.xml");
注意:事件處理函數代碼使用oXmlDom而不是this關鍵字,這是JavaScript中ActiveX對象的特殊之處。
load()方法可以接受部分的、相對的或者完整的XML文件路徑。eg.
oXmlDom.load("test.xml");
oXmlDom.load("../test.xml");
oXmlDom.load("http://www.amigo.com/test.xml")。
3) 獲取XML
把XML載入到DOM中後,還需將XML取出來,微軟爲每個節點(包括文檔節點)都添加了一個xml特性,使得這個操作十分方便,它會將XML表現形式作爲
字符串返回。所以獲取載入後的XML十分簡單:
oXmlDom.load("test.xml");
alert(oXmlDom.xml);
也可以獲取某個特定節點的XML:
var oNode = oXmlDom.documentElements.childNodes[1];
alert(oNode.xml);
xml特性是隻讀的,如果嘗試直接對其進行賦值會產生錯誤。
4) 解釋錯誤
微軟的XML DOM的parseError的特性包含了關於解析XML代碼時所遇到的問題的所有信息。
parseError特性實際上是包含以下特性的對象:
errorCode--表示所發生的錯誤類型的數字代號(沒有錯誤時爲0);
filePos--錯誤發生在文件中的位置;
line--遇到錯誤的行號;
linepos--在遇到錯誤的那一行上的字符的位置;
reason--對錯誤的一個解釋;
srcText--造成錯誤的代碼;
url--造成錯誤的文件的URL(如果可用)。
可直接對parseError自身取值,它會返回errorCode的值。Eg.
if (oXmlDom. parseError != 0) {
//...
}
可以使用parseError對象來創建自己的錯誤對話框:
if (oXmlDom. parseError != 0) {
var oError = oXmlDom. parseError;
alert("錯誤發生!&#92;nerrorCode: " + oError. errorCode
+ "&#92;nLine:" + oError.line + "&#92;nLine Pos: " + oError. linepos
+ "&#92;nReason: " + oError. reason);
}

2. Mozilla中的XML DOM支持
略。

3. 通用接口
有了跨瀏覽器的解決方案時,使用XML DOM進行開發才真正有用。IE和Mozilla的實現之間有着很明顯的區別,開發時會造成很嚴重的問題。需要找
出一套能在兩種瀏覽器中都可以使用XML DOM的通用方法。
1) 修改DOM創建
最簡單方法是創建僞類,使其通過var oXmlDom = new XmlDom ();來創建XML DOM。在其構造函數中進行瀏覽器檢測,eg.
function XmlDom() {
if (window.ActiveObject) {
//IE-specific code
} else if (document.implementation && document.implementation.createDocument) {
//DOM-specific code
} else {
throw new Error("你的瀏覽器不支持XML DOM對象");
}
}
2) IE分支
將上節的IE中創建DOM的代碼轉貼到上述代碼中。
3) Mozilla分支
略。
4) 完整代碼
完整代碼如下所示:
function XmlDom() {
if (window.ActiveXObjext) {
var arrSignatures = {"MSXML2.DOMDocument5.0", "MSXML2.DOMDocument4.0", "MSXML2.DOMDocument3.0", "MSXML2.DOMDocument", "Microsoft
XmlDom"};
for (var i= 0; i < arrSignatures.length; i++) {
try {
var oXmlDom = new ActiveXObject(arrSignatures);
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.addEventListener("load", function()) {
this.__checkForErrors__();
this.__changeReadyState__(4);
}, false);
return oXmlDom;
} else {
throw new Error("你的瀏覽器不支持XML DOM對象");
}
}
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..lineppos = -1;
this.parseError..reason = null;
this.parseError.srcText = null;
this.parseError..url = null;
};
Document.prototype.__checkForErrors__ = function() {
if (this.documentElement.tagName == "parseError") {
var reError = />([&#92;s&#92;S]*?)Location:([&#92;s&#92;S]*?)Line Number (&#92;d+), Column (&#92;d+):<sourcetext>([&#92;s&#92;S]*?)(?:&#92;-*&#92;^)/;
reError.text(this.xml);
this.parseError..errorCode = -999999;
this.parseError..reason = RegExp.$1p;
this.parseError..url = this.parseError..$2;
this.parseError..line = pauseInt(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 = 0; I < oXmlDom.childNodes.length; i++) {
var oNewNode = this.importNode(oXmlDom.childNodes, 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)L
};
Node.prototype.__defineGetter__("xml", function()) {
var oSerializer = new XMLSerializer();
return oSerializer.serializeToString(this. "text/xml");
});
}
二. 瀏覽器對XPath的支持
XPath是一種可以在XML代碼中定位數據的方式。
1. 簡介
每個XPath表達式有兩部分:一個上下文節點和一個節點模式。前者提供了節點模式起始的位置。節點模式是由一個或多個節點選擇器組成的字符串。
Eg. <?xml version="1.0"?>
<employees>
<employee title="軟件工程師">
<name>阿蜜果</name>
</employee>
<employee title="測試工程師">
<name>amigo</name>
</employee>
</employees>若XPath表達式employee/name,匹配的是<name>阿蜜果</name>和<name>amigo</name>,若要選擇<employee/>元素的第一個
<name/>元素,可用employee[position() == 1]/name。在XPath中,方框記號用於爲某個節點提供更加確切的信息,position()用於返回元素在父節
點下的位置。
除了未知和名稱外,還可以使用不同的方法來匹配元素,若要選擇所有title特性爲"軟件工程師"的<employee/>元素,對應的表達式爲:
employee[@title = "軟件工程師"]
其中@是attribute的縮寫。
2. IE中XPath的支持
每個節點的都有兩個可用於獲取匹配XPath模式的節點的方法:
selectNodes():用於匹配某個模式的節點的集合;
selectSingleNode():用於返回匹配給定模式的第一個節點。
eg. varlstNodes = oXmlDom.documentElement.selectNodes("employee/name");
返回包含所有匹配給定模式的節點的NodeList,可以通過如下方式迭代所有的元素:
for (var i = 0; i < varlstNodes.length; i++) {
alert(varlstNodes);
}
如果沒有匹配的節點,返回的NodeList的length爲0。
3. Mozilla中XPath的支持
略。
三. 瀏覽器的XSLT支持
XSLT:可擴展樣式表語言轉換,可由一些模板組成。模板屬於XML的某個特性的一部分(使用XPath指定),它可以決定爲這一部分輸出什麼文本。通
過爲不同的元素和條件定義模板,XSLT樣式表變成了一種XML的解析器。
1. IE對XSLT的支持
從MSXML3.0開始,IE就完全支持XSLT1.0了。對於在IE6.0以前的版本,還需要安裝新版的MSXML。
最簡單的XSLT轉換的方法是:分別將XML源代碼和XSLT文件載入各自的DOM,並使用特有的transformNode方法:
oXmlDom.load("employees.xml");
oXslDom.load("employees.xslt");
var sResult = oXmlDom. transformNode(oXslDom);
其實,也可以不從文檔層次轉換,而從節點層次轉換,如果從某個節點調用transformNode(),則從這個點開始轉換,但是XSLT能訪問包含這個節點
的整個XML文檔。
在IE中使用XSLT的另外一個比較複雜的方法是,使用XSL模板和處理器。這種方法必須使用MSXML的其他幾個ActiveX控件。首先XSLT文件必須載入到
一個自由線程DOM文檔中,代碼如下:
var oXslDom = new ActiveXObject("MSXML2.FreeThreadedDOMDocumnet");
oXslDom.asyn = false;
oXslDom.load("employees.xml");
自由線程DOM文檔建立並加載好後,必須將其分配到XSL模板中,這是另一個ActiveX對象:
var oTemplate = new ActiveXObject(":MSXML2.XSLTemplate");
oTemplate.stylesheet = oXslDom;
然後,可以用XSL模板來創建一個XSL處理器:
var oProcessor = oTemplate.createProcessor();
創建處理器後,將input特性設置爲要進行轉換的XML DOM節點,然後調用transform()方法:
oProcessor.input = oXmlDom;
oProcessor.transform();
然後將從output特性中訪問結果字符串:
var sResult = oProcessor.output;
這個複雜的方法模仿了transformNode()的功能,但該方法允許更多地控制XSLT。
注意:MSXML只支持XSLT1.0。MSXML的開發自從轉到.NET Framework後就停止了。可能在未來的某天,JavaScript會允許訪問XML和XSL的.NET對象。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章