一、IE讀取XML var xmlDoc; xmlDoc = new ActiveXObject( "Msxml2.DOMDocument" ); xmlDoc.loadXML(xml); //取的節(jié)點(diǎn) var points = xmlDoc.documentElement.getElementsByTagName("point"); //取得節(jié)點(diǎn)的內(nèi)容值 points[i].childNodes[1].text 二、FireFox讀取XML Firefox中創(chuàng)建一個(gè)XML DOM,需要調(diào)用document.implementation對(duì)象的createDocument()方法。該方法接受三個(gè)參數(shù):第一個(gè)參數(shù)是包含文檔所使用的命名空間URI的字符串;第二個(gè)參數(shù)是包含文檔根元素名稱的字符串;第三個(gè)參數(shù)是要?jiǎng)?chuàng)建的文檔類型(也稱為doctype)。如果要?jiǎng)?chuàng)建空的DOM文檔,則代碼如下所示: var oXmlDom = document.implementation.createDocument("", "", null); 前兩個(gè)參數(shù)是空字符串,第三個(gè)參數(shù)為null,這樣可以確保生成一個(gè)徹底的空文檔。事實(shí)上,現(xiàn)在Firefox中并不提供針對(duì)文檔類型的JavaScript支持,所以第三個(gè)參數(shù)總是為null。如果要?jiǎng)?chuàng)建包含文檔元素的XML DOM,那么可以在第二個(gè)參數(shù)中指定標(biāo)簽名稱: var oXmlDom = document.implementation.createDocument("", "books", null); 這段代碼創(chuàng)建了一個(gè)XML DOM,其documentElement是<books/>。如果要?jiǎng)?chuàng)建包含指定命名空間的DOM,可以在第一個(gè)參數(shù)中指定命名空間URI: var oXmlDom = document.implementation.createDocument(http://www.site1.com, "books", null); 當(dāng)在createDocument()方法中指定命名空間時(shí), Firefox會(huì)自動(dòng)附上前綴a0以表示命名空間URI: <a0:books xmlns:a0="http://www.site1.com" /> 接著,你可以通過(guò)程序來(lái)填充XML文檔,不過(guò)在一般情況下,還需要在空的XML DOM對(duì)象中載入現(xiàn)有的XML文檔。 1. 在Firefox中載入XML數(shù)據(jù) 在Firefox中,將XML載入XML DOM的方法和微軟采用的方法大致相同,只存在一個(gè)顯著區(qū)別:Firefox只支持load()方法。因此,在這兩種瀏覽器中載入外部XML數(shù)據(jù)的代碼是相同的: oXmlDom.load("books.xml"); 與微軟的IE一樣,F(xiàn)irefox同樣實(shí)現(xiàn)了async屬性,該屬性的行為也與其一致:將async設(shè)置為false,表示以同步模式載入文檔;否則,以異步模式載入文檔。 Firefox的XML DOM實(shí)現(xiàn)和微軟的XML DOM實(shí)現(xiàn)還存在另一個(gè)不同,即Firefox不支持readyState屬性及onreadystatechange事件處理函數(shù)。在Firefox中,支持load事件和onload事件處理函數(shù)。在文檔完全載入后將觸發(fā)load事件: oXmlDom.load("books.xml"); oXmlDom.onload = function () { //文檔完全載入后的操作 }; 正如前面所說(shuō),在Firefox的XML DOM實(shí)現(xiàn)中,并沒有l(wèi)oadXML()方法,不過(guò)通過(guò)Firefox中的DOMParser類可以模擬loadXML()的行為。該類有一個(gè)名為parseFromString()的方法,用來(lái)載入字符串并解析成文檔: var sXml = "<root><person><name>Jeremy McPeak</name></person></root>"; var oParser = new DOMParser(); var oXmlDom = oParser.parseFromString(sXml,"text/xml"); 在這段代碼中,創(chuàng)建了一個(gè)XML字符串,并作為參數(shù)傳遞給DOMParser的parseFromString()方法。parseFromString()方法的兩個(gè)參數(shù)分別是XML字符串和數(shù)據(jù)的內(nèi)容類型(一般設(shè)置為text/xml)。parseFromString()方法返回XML DOM對(duì)象,因此這里得到的oXmlDom與第一個(gè)例子相同。 2. 在Firefox中獲取XML數(shù)據(jù) 盡管存在這樣那樣的不同,但I(xiàn)E和Firefox中用于獲取文檔中XML數(shù)據(jù)的大多數(shù)屬性和方法是一致的。正如在IE中,可以使用documentElement屬性來(lái)獲取文檔的根元素,例如: var oRoot = oXmlDom.documentElement; Firefox同樣支持W3C標(biāo)準(zhǔn)屬性,包括childNodes、firstChild、lastChild、nextSibling、nodeName、nodeType、nodeValue、ownerDocument、parentNode和previousSibling。不幸的是,對(duì)于微軟專有的text和xml屬性,F(xiàn)irefox并不支持,不過(guò)可以利用其他方法來(lái)模擬該屬性的行為。 大家應(yīng)該還記得,text屬性返回了當(dāng)前節(jié)點(diǎn)的內(nèi)容,或者是當(dāng)前節(jié)點(diǎn)及其子節(jié)點(diǎn)的內(nèi)容。這不僅僅返回當(dāng)前節(jié)點(diǎn)的文本,還有所有子節(jié)點(diǎn)的文本,因此要模擬該功能實(shí)現(xiàn)是十分容易的。下面這個(gè)簡(jiǎn)單的函數(shù)就能夠完成該功能,該函數(shù)唯一的參數(shù)是一個(gè)節(jié)點(diǎn): function getText(oNode) { var sText = ""; for (var i = 0; i < oNode.childNodes.length; i++) { if (oNode.childNodes[i].hasChildNodes()) { sText += getText(oNode.childNodes[i]); } else { sText += oNode.childNodes[i].nodeValue; } } return sText; } 在getText()函數(shù)中,sText變量用來(lái)保存獲取的所有文本。接著對(duì)oNode的子節(jié)點(diǎn)使用for循環(huán)進(jìn)行遍歷,檢查每個(gè)子節(jié)點(diǎn)是否包含子節(jié)點(diǎn)。如果有子節(jié)點(diǎn),那么就將其childNode傳給getText()函數(shù),并進(jìn)行同樣的處理;如果沒有子節(jié)點(diǎn),那么將當(dāng)前節(jié)點(diǎn)的nodeValue加到字符串中(對(duì)文本節(jié)點(diǎn)而言,這只是文本字符串)。處理了所有子節(jié)點(diǎn)后,該函數(shù)返回變量sText。 IE中的xml屬性將存放對(duì)當(dāng)前節(jié)點(diǎn)包含的所有XML進(jìn)行序列化的結(jié)果。在Firefox中,提供了一個(gè)名為XMLSerializer對(duì)象來(lái)完成這一功能。該對(duì)象提供一個(gè)使用JavaScript可訪問(wèn)的serializeToString()方法,使用該方法可以對(duì)XML數(shù)據(jù)進(jìn)行序列化。 function serializeXml(oNode) { var oSerializer = new XMLSerializer(); return oSerializer.serializeToString(oNode); } serializeXml()函數(shù)以XML節(jié)點(diǎn)作為參數(shù),創(chuàng)建一個(gè)XMLSerializer對(duì)象,并將該節(jié)點(diǎn)傳給serializeToString()方法。該方法將向調(diào)用者返回XML數(shù)據(jù)的字符串表示。 對(duì)于節(jié)點(diǎn)操作的DOM方法,F(xiàn)irefox與IE大致相同。參見“在IE中操作DOM”小節(jié)。 3. 在Firefox中處理錯(cuò)誤 Firefox與IE的錯(cuò)誤處理并不一樣。當(dāng)IE遇到錯(cuò)誤時(shí),它會(huì)填充parseError對(duì)象;而當(dāng)Firefox遇到錯(cuò)誤時(shí),它會(huì)將包含錯(cuò)誤信息的XML文檔載入到XML DOM文檔中??聪旅娴倪@個(gè)例子: 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") { //沒有錯(cuò)誤發(fā)生,進(jìn)行所需操作 } else { alert("An Error Occurred"); } 在突出顯示的代碼行中,你會(huì)發(fā)現(xiàn)其中將產(chǎn)生一個(gè)錯(cuò)誤:XML字符串格式不正確(因?yàn)?lt;person>元素不完整,沒有相應(yīng)的</person>元素)。當(dāng)載入錯(cuò)誤的XML時(shí),XML DOM對(duì)象將會(huì)載入一個(gè)documentElement為<parsererror/>的錯(cuò)誤文檔。我們可以通過(guò)檢查documentElement的tagName屬性來(lái)很容易地確定是否發(fā)生錯(cuò)誤。如果tagName屬性不是parsererror,就可以確定沒有發(fā)生任何錯(cuò)誤。 在本例中,可能會(huì)生成如下所示的錯(cuò)誤文檔: <parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">XML Parsing Error: mismatched tag. Expected: </person>. Location: http://yoda/fooreader/test.htm Line Number 1, Column 43:<sourcetext><root><person><name>Jeremy McPeak</name></root> ------------------------------------------^</sourcetext></parsererror> 所有的錯(cuò)誤信息都包含在錯(cuò)誤文檔的文本中。如果要通過(guò)程序使用這些錯(cuò)誤信息,那么首先就要對(duì)其進(jìn)行解析。最簡(jiǎn)單的方法是使用一個(gè)稍長(zhǎng)的正則表達(dá)式: var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/; 該正則表達(dá)式將錯(cuò)誤文檔分為五個(gè)部分:錯(cuò)誤消息、發(fā)生錯(cuò)誤的文件名、行號(hào)、該行中發(fā)生錯(cuò)誤的位置,以及發(fā)生錯(cuò)誤的源代碼。使用正則表達(dá)式對(duì)象的test()方法可以使用這些信息: if (oXmlDom.firstChild.tagName != "parsererror") { //沒有錯(cuò)誤發(fā)生,進(jìn)行所需操作 } 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); 正則表達(dá)式捕獲到的第一部分?jǐn)?shù)據(jù)是錯(cuò)誤消息,第二部分是文件名,第三部分是行號(hào),第四部分是行內(nèi)位置,第五部分是源碼。你可以使用這些解析后的信息來(lái)創(chuàng)建自定義的錯(cuò)誤消息: var str = "An error occurred!!\n" + "Description: " + RegExp.$1 + "\n" + "File: " + RegExp.$2 + "\n" + "Line: " + RegExp.$3 + "\n" + "Line Position: " + RegExp.$4 + "\n" + "Source Code: " + RegExp.$5; alert(str); 如果發(fā)生錯(cuò)誤,那么alert()方法會(huì)以易于閱讀的格式在警告框中來(lái)顯示相關(guān)的錯(cuò)誤信息。 經(jīng)過(guò)學(xué)習(xí)參考其他文章,終于在IE和FF下都可以輸出了 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script language="javascript"> var xmlDoc; var browse=""; function loadXML() { var fileRoute="books.xml" if (window.ActiveXObject) { xmlDoc = new ActiveXObject('Msxml2.DOMDocument'); xmlDoc.async=false; xmlDoc.load(fileRoute); browse="ie"; } else if (document.implementation && document.implementation.createDocument) { xmlDoc=document.implementation.createDocument('', '', null); xmlDoc.load(fileRoute); browse="ff"; } else { alert( '未做與該瀏覽器的兼容!'); } } function getmessage() { var msg='<table border="1" cellspacing="0" cellpadding="0" width="500">'; msg+='<tr><td width="90"></td><td width="100">圖書編號(hào)</td><td width="100">種類編號(hào)</td><td width="110">圖書名稱</td><td width="100">作者</td></tr>' if(browse=="ff") { var cNodes = xmlDoc.getElementsByTagName("book"); for(j=0;j<cNodes.length;j++) { var bookID=xmlDoc.getElementsByTagName("book")[j].getAttribute("id"); var sortID=xmlDoc.getElementsByTagName("book")[j].getAttribute("sortID"); var bookTitle=xmlDoc.getElementsByTagName("title")[j].childNodes[0].nodeValue; var bookAuthor=xmlDoc.getElementsByTagName("author")[j].childNodes[0].nodeValue; msg+='<tr><td>'+j+'</td><td>'+bookID+'</td><td width="100">'+sortID+'</td><td width="190">'+bookTitle+'</td><td width="120">'+bookAuthor+'</td></tr>' } } else if(browse=="ie") { var state = xmlDoc.readyState; if (state == 4) { var oNodes = xmlDoc.selectNodes("//books/book"); for(j=0;j<oNodes.length;j++) { var bookID=oNodes[j].getAttribute("id"); var sortID=oNodes[j].getAttribute("sortID"); var bookTitle=oNodes[j].childNodes[0].text; var bookAuthor=oNodes[j].childNodes[1].text; msg+='<tr><td>'+j+'</td><td>'+bookID+'</td><td width="100">'+sortID+'</td><td width="190">'+bookTitle+'</td><td width="120">'+bookAuthor+'</td></tr>' } } } msg+='</table>'; //alert(msg) document.getElementById("bookList").innerHTML=msg; } </script> </head> <body onload="loadXML();"> <div id="bookList" style="width:500px;"> </div> <table border="0" cellspacing="0" cellpadding="0" width="500"> <tr> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </table> <input name="button" type="button" onclick="getmessage()" value="onclick" /> </body> </html> books.xml <?xml version="1.0" encoding="gb2312"?> <books> <book id="4" sortID="a4"> <title>author4aa</title> <author>author4</author> </book> <book id="5" sortID="a5"> <title>author55</title> <author>author5</author> </book> <book id="6" sortID="a6"> <title>booktitle</title> <author>author6</author> </book> <book id="7" sortID="a7"> <title>booktitle</title> <author>author7</author> </book> <book id="8" sortID="a8"> <title>booktitle</title> <author>author8</author> </book> <book id="15" sortID="a15"> <title>author155</title> <author>author15</author> </book> </books>