1、IE讀取XML
var xmlDoc;
xmlDoc = new ActiveXObject( "Msxml2.DOMDocument" );
xmlDoc.loadXML(xml);
//取的節點
var points = xmlDoc.documentElement.getElementsByTagName("point");
//取得節點的內容值
points.childNodes[1].text
二、firefox讀取XML
Firefox中建立一個XML DOM,須要調用document.implementation對象的createDocument()方法。該方法接受三個參數:第一個參數是包含文檔所使用的命名空間URI的字符串;第二個參數是包含文檔根元素名稱的字符串;第三個參數是要建立的文檔類型(也稱爲doctype)。若是要建立空的DOM文檔,則代碼以下所示:
var oXmlDom = document.implementation.createDocument("", "", null);
前兩個參數是空字符串,第三個參數爲null,這樣能夠確保生成一個完全的空文檔。事實上,如今Firefox中並不提供針對文檔類型的JavaScript支持,因此第三個參數老是爲null。若是要建立包含文檔元素的XML DOM,那麼能夠在第二個參數中指定標籤名稱:
var oXmlDom = document.implementation.createDocument("", "books", null);
這段代碼建立了一個XML DOM,其documentElement是<books/>。若是要建立包含指定命名空間的DOM,能夠在第一個參數中指定命名空間URI:
var oXmlDom = document.implementation.createDocument("http://www.site1.com",
"books", null);
當在createDocument()方法中指定命名空間時, Firefox會自動附上前綴a0以表示命名空間URI:
<a0:books xmlns:a0="http://www.site1.com" />
接着,你能夠經過程序來填充XML文檔,不過在通常狀況下,還須要在空的XML DOM對象中載入現有的XML文檔。
1. 在Firefox中載入XML數據
在Firefox中,將XML載入XML DOM的方法和微軟採用的方法大體相同,只存在一個顯著區別:Firefox只支持load()方法。所以,在這兩種瀏覽器中載入外部XML數據的代碼是相同的:
oXmlDom.load("books.xml");
與微軟的IE同樣,Firefox一樣實現了async屬性,該屬性的行爲也與其一致:將async設置爲false,表示以同步模式載入文檔;不然,以異步模式載入文檔。
Firefox的XML DOM實現和微軟的XML DOM實現還存在另外一個不一樣,即Firefox不支持readyState屬性及onreadystatechange事件處理函數。在Firefox中,支持load事件和onload事件處理函數。在文檔徹底載入後將觸發load事件:
oXmlDom.load("books.xml");
oXmlDom.onload = function () {
//文檔徹底載入後的操做
};
正如前面所說,在Firefox的XML DOM實現中,並無loadXML()方法,不過經過Firefox中的DOMParser類能夠模擬loadXML()的行爲。該類有一個名爲parseFromString()的方法,用來載入字符串並解析成文檔:
var sXml = "<root><person><name>Jeremy McPeak</name></person></root>";
var oParser = new DOMParser();
var oXmlDom = oParser.parseFromString(sXml,"text/xml");
在這段代碼中,建立了一個XML字符串,並做爲參數傳遞給DOMParser的parseFromString()方法。parseFromString()方法的兩個參數分別是XML字符串和數據的內容類型(通常設置爲text/xml)。parseFromString()方法返回XML DOM對象,所以這裏獲得的oXmlDom與第一個例子相同。
2. 在Firefox中獲取XML數據
儘管存在這樣那樣的不一樣,但IE和Firefox中用於獲取文檔中XML數據的大多數屬性和方法是一致的。正如在IE中,可使用documentElement屬性來獲取文檔的根元素,例如:
var oRoot = oXmlDom.documentElement;
Firefox一樣支持W3C標準屬性,包括childNodes、firstChild、lastChild、nextSibling、nodeName、nodeType、nodeValue、ownerDocument、parentNode和previousSibling。不幸的是,對於微軟專有的text和xml屬性,Firefox並不支持,不過能夠利用其餘方法來模擬該屬性的行爲。
你們應該還記得,text屬性返回了當前節點的內容,或者是當前節點及其子節點的內容。這不只僅返回當前節點的文本,還有全部子節點的文本,所以要模擬該功能實現是十分容易的。下面這個簡單的函數就可以完成該功能,該函數惟一的參數是一個節點:
function getText(oNode) {
var sText = "";
for (var i = 0; i < oNode.childNodes.length; i++) {
if (oNode.childNodes.hasChildNodes()) {
sText += getText(oNode.childNodes);
} else {
sText += oNode.childNodes.nodeValue;
}
}
return sText;
}
在getText()函數中,sText變量用來保存獲取的全部文本。接着對oNode的子節點使用for循環進行遍歷,檢查每一個子節點是否包含子節點。若是有子節點,那麼就將其childNode傳給getText()函數,並進行一樣的處理;若是沒有子節點,那麼將當前節點的nodeValue加到字符串中(對文本節點而言,這只是文本字符串)。處理了全部子節點後,該函數返回變量sText。
IE中的xml屬性將存放對當前節點包含的全部XML進行序列化的結果。在Firefox中,提供了一個名爲XMLSerializer對象來完成這一功能。該對象提供一個使用JavaScript可訪問的serializeToString()方法,使用該方法能夠對XML數據進行序列化。
function serializeXml(oNode) {
var oSerializer = new XMLSerializer();
return oSerializer.serializeToString(oNode);
}
serializeXml()函數以XML節點做爲參數,建立一個XMLSerializer對象,並將該節點傳給serializeToString()方法。該方法將向調用者返回XML數據的字符串表示。
對於節點操做的DOM方法,Firefox與IE大體相同。參見「在IE中操做DOM」小節。
3. 在Firefox中處理錯誤
Firefox與IE的錯誤處理並不同。當IE遇到錯誤時,它會填充parseError對象;而當Firefox遇到錯誤時,它會將包含錯誤信息的XML文檔載入到XML DOM文檔中。看下面的這個例子:
var sXml = "<root><person><name>Jeremy McPeak</name></root>";
var oParser = new DOMParser();
var oXmlDom = oParser.parseFromString(sXml,"text/xml");
if (oXmlDom.documentElement.tagName != "parsererror") {
//沒有錯誤發生,進行所需操做
} else {
alert("An Error Occurred");
}
在突出顯示的代碼行中,你會發現其中將產生一個錯誤:XML字符串格式不正確(由於<person>元素不完整,沒有相應的</person>元素)。當載入錯誤的XML時,XML DOM對象將會載入一個documentElement爲<parsererror/>的錯誤文檔。咱們能夠經過檢查documentElement的tagName屬性來很容易地肯定是否發生錯誤。若是tagName屬性不是parsererror,就能夠肯定沒有發生任何錯誤。
在本例中,可能會生成以下所示的錯誤文檔:
<parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">XML
Parsing Error: mismatched tag. Expected: </person>.
Location: [url]http://yoda/fooreader/test.htm[/url]
Line Number 1, Column 43:<sourcetext><root><person><name>Jeremy
McPeak</name></root>
------------------------------------------^</sourcetext></parsererror>
全部的錯誤信息都包含在錯誤文檔的文本中。若是要經過程序使用這些錯誤信息,那麼首先就要對其進行解析。最簡單的方法是使用一個稍長的正則表達式:
var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column
(\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
該正則表達式將錯誤文檔分爲五個部分:錯誤消息、發生錯誤的文件名、行號、該行中發生錯誤的位置,以及發生錯誤的源代碼。使用正則表達式對象的test()方法可使用這些信息:
if (oXmlDom.firstChild.tagName != "parsererror") {
//沒有錯誤發生,進行所需操做
} else {
var oXmlSerializer = new XMLSerializer();
var sXmlError = oXmlSerializer.serializeToString(oXmlDom);
var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column
(\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
reError.test(sXmlError);
正則表達式捕獲到的第一部分數據是錯誤消息,第二部分是文件名,第三部分是行號,第四部分是行內位置,第五部分是源碼。你可使用這些解析後的信息來建立自定義的錯誤消息:
var str = "An error occurred!! " +
"Description: " + RegExp.$1 + " " +
"File: " + RegExp.$2 + " " +
"Line: " + RegExp.$3 + " " +
"Line Position: " + RegExp.$4 + " " +
"Source Code: " + RegExp.$5;
alert(str);
若是發生錯誤,那麼alert()方法會以易於閱讀的格式在警告框中來顯示相關的錯誤信息。