一、IE读取XML var xmlDoc; xmlDoc = new ActiveXObject( "Msxml2.DOMDocument" ); xmlDoc.loadXML(xml); //取的节点 var points = xmlDoc.documentElement.getElementsByTagName("point"); //取得节点的内容值 points[i].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[i].hasChildNodes()) { sText += getText(oNode.childNodes[i]); } else { sText += oNode.childNodes[i].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: http://yoda/fooreader/test.htm 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!!\n" + "Description: " + RegExp.$1 + "\n" + "File: " + RegExp.$2 + "\n" + "Line: " + RegExp.$3 + "\n" + "Line Position: " + RegExp.$4 + "\n" + "Source Code: " + RegExp.$5; alert(str); 如果发生错误,那么alert()方法会以易于阅读的格式在警告框中来显示相关的错误信息。 经过学习参考其他文章,终于在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">图书编号</td><td width="100">种类编号</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>