javascript之XML DOM对象

javacript中对xml dom的支持,与其他任何特性一样面临着浏览器兼容问题。

  一 IE中的XML DOM

  1.微软通过ActiveX的MSXML库提供了支持,通过:

  var oXmlDom = new ActiveXObject("MSXML2.DOMDocument.5.0")得到一个XML DOM对象,这是在IE6中的,如果你的IE是更老版本的,可以使用下面的函数得到,如果你没有安装MSXML,将不能得到:
+展开
-JavaScript
function createXMLDOM() {
    
      var arrSignatures = ["MSXML2.DOMDocument.5.0""MSXML2.DOMDocument.4.0",
                 "MSXML2.DOMDocument.3.0""MSXML2.DOMDocument",
                 "Microsoft.XmlDom"];
                
      for (var i=0; i < arrSignatures.length; i++) {
        try {
        
          var oXmlDom = new ActiveXObject(arrSignatures[i]);
          
          return oXmlDom;
        
        } catch (oError) {
          //ignore
        }
      }       
      
      throw new Error("你的系统没有安装MSXML");     
    }


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

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

  oXmlDom.load("test.xml");
  oXmlDom.loadXML("<root></root>");然后这个oXmlDom就可以使用所有的DOM对象方法,比如documentElement.tagName,参见:

  《javascript之DOM技术(一)》

  《javascript之dom技术(二)》

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

  oXmlDom.async=true;

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

  0——准备载入

  1——正在载入

  2——载入完成

  3——载入完成并可用,但有一部分数据也许不可用

  4——完全载入,完全可用。

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

+展开
-JavaScript
oXmlDom.onreadystatechange = function () {
        if (oXmlDom.readyState == 4) {
          alert("load test.xml done!");
          alert("Tag name of the root element is " + oXmlDom.documentElement.tagName);
          alert("The root element has this many children: " + oXmlDom.documentElement.childNodes.length);
  
        }
      };
5.IE的XML DOM对象有一个xml属性,用来返回xml文件的字符串形式,比如

+展开
-JavaScript
oXmlDom.async=false;
oXmlDom.load("test.xml");
alert(oXmlDom.xml);
alert出:


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

     
+展开
-JavaScript
 oXmlDom.async = false;
      oXmlDom.load("errors.xml");
      
      //0表示没有错误
      if (oXmlDom.parseError != 0) {
        var oError = oXmlDom.parseError;
      
        alert("An error occurred:错误代码: "
           + oError.errorCode 
           + "行数: " + oError.line 
           + "列数: " + oError.linepos
           + "原因: " + oError.reason);
           
      }

  二.Mozilla的XML DOM对象

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

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

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

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

  这段代码创建了一个<a0:root xmlns="http://www.rubyeye.net"/>的XML DOM对象

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

+展开
-JavaScript
oXmlDom.async=false;
oXmlDom.load("test.xml");


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

+展开
-JavaScript
oXmlDom.onload=function(){
alert("done");
}

  oXmlDom.load("test.xml");


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

+展开
-JavaScript
  var oParser=new DOMParser();

  var oXmlDom=oParser.parseFromString("<root><child/></root>,"text/xml");


  两个参数:要解析的XML字符串以及字符串的内容类型(只能为text/xml或者application/xml)。

  不过我们可以实现自己的loadXML方法:

 
+展开
-JavaScript
Document.prototype.loadXML = function (sXml) {
  
      var oParser = new DOMParser();
      var oXmlDom = oParser.parseFromString(sXml, "text/xml");
    
      //删除原文档内容
      while (this.firstChild) {
        this.removeChild(this.firstChild);
      }
      //导入新的文档内容
      for (var i=0; i < oXmlDom.childNodes.length; i++) {
        var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
        this.appendChild(oNewNode);
      }
    
    };

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

  var sXml=oSerializer.serializeToString(oXmlDom,"text/xml");同样两个参数:XML DOM对象以及转化成的文档类型。

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

Node.prototype.__defineGetter__("xml",function(){
var oSerializer=new XMLSerializer();
var sXml=oSerializer.serializeToString(this,"text/xml");
});
以后就可以以IE的方式,oXmlDom.xml来获取XML文档内容。

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

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



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

+展开
-JavaScript
function XmlDom() {
  //通过对象/属性检测法,判断是IE来是Mozilla
  if (window.ActiveXObject) {
    var arrSignatures = ["MSXML2.DOMDocument.5.0""MSXML2.DOMDocument.4.0",
               "MSXML2.DOMDocument.3.0""MSXML2.DOMDocument",
               "Microsoft.XmlDom"];
            
    for (var i=0; i < arrSignatures.length; i++) {
      try {
    
        var oXmlDom = new ActiveXObject(arrSignatures[i]);
      
        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);
  
    //创建Mozilla版本的parseError对象
    oXmlDom.parseError = {
      valueOf: function () { return this.errorCode; },
      toString: function () { return this.errorCode.toString() }
    };
    
    //初始化parseError对象
    oXmlDom.__initError__();
        
    
    oXmlDom.addEventListener("load"function () {
      this.__checkForErrors__();
      this.__changeReadyState__(4);
    }, false);
  
    return oXmlDom;    
    
  } else {
    throw new Error("Your browser doesn't support an XML DOM object.");
  }
}
  
//此处用到了该书中一个浏览器系统检测js文件,如果是Mozilla
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();
    }
  };
  //初始化parseError对象
  Document.prototype.__initError__ = function () {
    this.parseError.errorCode = 0;
    this.parseError.filepos = -1;
    this.parseError.line = -1;
    this.parseError.linepos = -1;
    this.parseError.reason = null;
    this.parseError.srcText = null;
    this.parseError.url = null;
  };
  
  Document.prototype.__checkForErrors__ = function () {
  
    if (this.documentElement.tagName == "parsererror") {
  
      var reError = />([sS]*?)Location:([sS]*?)Line Number (d+), Column (d+):([sS]*?)(?:-*^)/;
  
      reError.test(this.xml);
      
      this.parseError.errorCode = -999999;
      this.parseError.reason = RegExp.$1;
      this.parseError.url = RegExp.$2;
      this.parseError.line = parseInt(RegExp.$3);
      this.parseError.linepos = parseInt(RegExp.$4);
      this.parseError.srcText = RegExp.$5;
    }
  };
  
   //定义Mozilla的loadXML方法 
  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 i=0; i < oXmlDom.childNodes.length; i++) {
      var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
      this.appendChild(oNewNode);
    }
    
    //载入后检查错误
    this.__checkForErrors__();
    
    //没有问题,设置readyState属性为4
    this.__changeReadyState__(4);
  
  };
  
  Document.prototype.__load__ = Document.prototype.load;
  
  Document.prototype.load = function (sURL) {
    this.__initError__();
    this.__changeReadyState__(1);
    this.__load__(sURL);
  };
  
  Node.prototype.__defineGetter__("xml"function () {
    var oSerializer = new XMLSerializer();
    return oSerializer.serializeToString(this"text/xml");
  });
  
}








加支付宝好友偷能量挖...


评论(0)网络
阅读(135)喜欢(0)JavaScript/Ajax开发技巧