[藏]不同浏览器的XMLDOM 对象

一 IE中的XML DOM
1.微软通过ActiveX的MSXML库提供了支持,通过:

 
  1. var oXmlDom = new ActiveXObject("MSXML2.DOMDocument.5.0")

得到一个XML DOM对象,这是在IE6中的,如果你的IE是更老版本的,可以使用下面的函数得到,如果你没有安装MSXML,将不能得到:

 
  1. function createXMLDOM() {
  2. var arrSignatures = ["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0",
  3. "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument",
  4. "Microsoft.XmlDom"];
  5. for (var i=0; i < arrSignatures.length; i++) {
  6. try {
  7. var oXmlDom = new ActiveXObject(arrSignatures[i]);
  8. return oXmlDom;
  9. } catch (oError) {
  10. //ignore
  11. }
  12. }
  13. throw new Error("你的系统没有安装MSXML");
  14. }

当然,如果你使用prototype库,可以使用Try.these函数。

2.XML DOM对象可以通过load和loadXML方法载入xml文件或者字符串:

 
  1. oXmlDom.load("test.xml");
  2. oXmlDom.loadXML("");

然后这个oXmlDom就可以使用所有的DOM对象方法,比如documentElement.tagName,参见:
《javascript之DOM技术(一)》
《javascript之dom技术(二)》

3.XML DOM默认是通过异步载入xml文件的,可以通过设置async值来选择是同步还是异步:

 
  1. oXmlDom.async=true;

4.IE的XML DOM拥有一个readyState值用来表示载入文件的状态:

0——准备载入
1——正在载入
2——载入完成
3——载入完成并可用,但有一部分数据也许不可用
4——完全载入,完全可用。

相应的有一个onreadystatechange事件,当状态改变时发生,我们可以通过监听此事件来判断XML DOM对象的可用性

 
  1. oXmlDom.onreadystatechange = function () {
  2. if (oXmlDom.readyState == 4) {
  3. alert("load test.xml done!");
  4. alert("Tag name of the root element is " + oXmlDom.documentElement.tagName);
  5. alert("The root element has this many children: " + oXmlDom.documentElement.childNodes.length);
  6. }
  7. };

5.IE的XML DOM对象有一个xml属性,用来返回xml文件的字符串形式,比如

 
  1. oXmlDom.async=false;
  2. oXmlDom.load("test.xml");
  3. alert(oXmlDom.xml);

alert出:
6.IE,当载入的XML文件或者字符串解析错误时,将产生一个parseError对象,我们在下面的代码中演示此对象的属性:

 
  1. oXmlDom.async = false;
  2. oXmlDom.load("errors.xml");
  3. //0表示没有错误
  4. if (oXmlDom.parseError != 0) {
  5. var oError = oXmlDom.parseError;
  6. alert("An error occurred:\n错误代码: "
  7. + oError.errorCode + "\n"
  8. + "行数: " + oError.line + "\n"
  9. + "列数: " + oError.linepos + "\n"
  10. + "原因: " + oError.reason);
  11. }

二.Mozilla的XML DOM对象
1.XML DOM对象的创建,符合DOM标准的,通过document.implementation.createDocument()方法。比如:

 
  1. var oXmlDom=document.implementation.createDocument("","",null);

这三个参数分别是文档命名空间、文档元素的标签名以及一个文档类型对象(总为null),比如:

 
  1. var oXmlDom=document.implementation.createDocument("http://www.rubyeye.net","root",null);

这段代码创建了一个的XML DOM对象

2.载入xml,Mozilla与IE不同的是只提供了一个load()方法用于载入xml文件,没有提供loadXML()方法用于载入XML字符串。同步载入XML文件的代码与IE相同:

 
  1. oXmlDom.async=false;
  2. oXmlDom.load("test.xml");

异步载入稍有不同,因为Mozilla并不支持readyState属性,并且没有onreadystatechange事件,它只有一个onload的事件,当载入完成时触发;或者说相当于IE的readyState属性等于4的状态。

 
  1. oXmlDom.onload=function(){
  2. alert("done");
  3. }
  4. oXmlDom.load("test.xml");

要将XML字符串解析为DOM对象,必须使用DOMParser对象:

 
  1. var oParser=new DOMParser();
  2. var oXmlDom=oParser.parseFromString(","text/xml");

两个参数:要解析的XML字符串以及字符串的内容类型(只能为text/xml或者application/xml)。
不过我们可以实现自己的loadXML方法:

 
  1. Document.prototype.loadXML = function (sXml) {
  2. var oParser = new DOMParser();
  3. var oXmlDom = oParser.parseFromString(sXml, "text/xml");
  4. //删除原文档内容
  5. while (this.firstChild) {
  6. this.removeChild(this.firstChild);
  7. }
  8. //导入新的文档内容
  9. for (var i=0; i < oXmlDom.childNodes.length; i++) {
  10. var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
  11. this.appendChild(oNewNode);
  12. }
  13. };

3.Mozilla没有提供IE的xml属性来返回XML文档内容,只能通过使用XMLSerializer对象:

 
  1. var oSerializer=new XMLSerializer();
  2. var sXml=oSerializer.serializeToString(oXmlDom,"text/xml");

同样两个参数:XML DOM对象以及转化成的文档类型。

同样,我们也可以给Mozilla的XML DOM对象定义一个属性xml,通过defineGetter方法:

 
  1. Node.prototype.__defineGetter__("xml",function(){
  2. var oSerializer=new XMLSerializer();
  3. var sXml=oSerializer.serializeToString(this,"text/xml");
  4. });

以后就可以以IE的方式,oXmlDom.xml来获取XML文档内容。

4。错误处理,同样与IE不同,Mozilla当解析错误时会返回一段代码,以标签包括其中的代码解释了错误发生的原因以及位置等信息,我们只有通过正则表达式解析此段代码,提取错误信息。

 
  1. var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):([\s\S]*?)(?:\-*\^)/;
  2. //返回代码的标签名为parsererror,表示错误发生
  3. if (oXmlDom.documentElement.tagName == "parsererror") {
  4. reError.test(oXmlDom.xml);
  5. alert("An error occurred:\n描述: "
  6. + RegExp.$1 + "\n"
  7. + "文件名: " + RegExp.$2 + "\n"
  8. + "行数: " + RegExp.$3 + "\n"
  9. + "列数: " + RegExp.$4 + "\n"
  10. + "原因: " + RegExp.$5);
  11. }

三,提供一个跨浏览器的XML DOM对象解决方案,来自于《javascript高级程序设计》

 
  1. function XmlDom() {
  2. //通过对象/属性检测法,判断是IE来是Mozilla
  3. if (window.ActiveXObject) {
  4. var arrSignatures = ["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0",
  5. "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument",
  6. "Microsoft.XmlDom"];
  7. for (var i=0; i < arrSignatures.length; i++) {
  8. try {
  9. var oXmlDom = new ActiveXObject(arrSignatures[i]);
  10. return oXmlDom;
  11. } catch (oError) {
  12. //ignore
  13. }
  14. }
  15. throw new Error("MSXML is not installed on your system.");
  16. //同上
  17. } else if (document.implementation && document.implementation.createDocument) {
  18. var oXmlDom = document.implementation.createDocument("","",null);
  19. //创建Mozilla版本的parseError对象
  20. oXmlDom.parseError = {
  21. valueOf: function () { return this.errorCode; },
  22. toString: function () { return this.errorCode.toString() }
  23. };
  24. //初始化parseError对象
  25. oXmlDom.__initError__();
  26. oXmlDom.addEventListener("load", function () {
  27. this.__checkForErrors__();
  28. this.__changeReadyState__(4);
  29. }, false);
  30. return oXmlDom;
  31. } else {
  32. throw new Error("Your browser doesn't support an XML DOM object.");
  33. }
  34. }
  35. //此处用到了该书中一个浏览器系统检测js文件,如果是Mozilla
  36. if (isMoz) {
  37. Document.prototype.readyState = 0;
  38. Document.prototype.onreadystatechange = null;
  39. Document.prototype.__changeReadyState__ = function (iReadyState) {
  40. this.readyState = iReadyState;
  41. if (typeof this.onreadystatechange == "function") {
  42. this.onreadystatechange();
  43. }
  44. };
  45. //初始化parseError对象
  46. Document.prototype.__initError__ = function () {
  47. this.parseError.errorCode = 0;
  48. this.parseError.filepos = -1;
  49. this.parseError.line = -1;
  50. this.parseError.linepos = -1;
  51. this.parseError.reason = null;
  52. this.parseError.srcText = null;
  53. this.parseError.url = null;
  54. };
  55. Document.prototype.__checkForErrors__ = function () {
  56. if (this.documentElement.tagName == "parsererror") {
  57. var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):([\s\S]*?)(?:\-*\^)/;
  58. reError.test(this.xml);
  59. this.parseError.errorCode = -999999;
  60. this.parseError.reason = RegExp.$1;
  61. this.parseError.url = RegExp.$2;
  62. this.parseError.line = parseInt(RegExp.$3);
  63. this.parseError.linepos = parseInt(RegExp.$4);
  64. this.parseError.srcText = RegExp.$5;
  65. }
  66. };
  67. //定义Mozilla的loadXML方法
  68. Document.prototype.loadXML = function (sXml) {
  69. this.__initError__();
  70. this.__changeReadyState__(1);
  71. var oParser = new DOMParser();
  72. var oXmlDom = oParser.parseFromString(sXml, "text/xml");
  73. while (this.firstChild) {
  74. this.removeChild(this.firstChild);
  75. }
  76. for (var i=0; i < oXmlDom.childNodes.length; i++) {
  77. var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
  78. this.appendChild(oNewNode);
  79. }
  80. //载入后检查错误
  81. this.__checkForErrors__();
  82. //没有问题,设置readyState属性为4
  83. this.__changeReadyState__(4);
  84. };
  85. Document.prototype.__load__ = Document.prototype.load;
  86. Document.prototype.load = function (sURL) {
  87. this.__initError__();
  88. this.__changeReadyState__(1);
  89. this.__load__(sURL);
  90. };
  91. Node.prototype.__defineGetter__("xml", function () {
  92. var oSerializer = new XMLSerializer();
  93. return oSerializer.serializeToString(this, "text/xml");
  94. });
  95. }

你可能感兴趣的:(JavaScript,xml,浏览器,IE,prototype)