JasSipt之XML DOM对象

翻译|其它|编辑:郝浩|2007-08-30 09:46:32.000|阅读 1024 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

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

IE  中的  XML DOM
1.
微软通过  ActiveX    MSXML  库提供了支持,通过:
 var oXmlDom = new ActiveXObject("MSXML2.DOMDocument.5.0")
得到一个  XML DOM  对象,这是在  IE6中的,如果你的  IE  是更老版本的,可以使用下面的函数得到,如果你没有安装  MSXML,将不能得到:

 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,参见:
 
javascriptDOM  技术(一)》
 
javascriptdom  技术(二)》

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

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

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

相应的有一个  onreadystatechange  事件,当状态改变时发生,我们可以通过监听此事件来判断  XML DOM  对象的可用性
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  文件的字符串形式,比如
oXmlDom.async=false;
oXmlDom.load("test.xml");
alert(oXmlDom.xml);
alert 
出:<root><child/><child/></root>

6.IE,当载入的  XML  文件或者字符串解析错误时,将产生一个  parseError  对象,我们在下面的代码中演示此对象的属性:
            oXmlDom.async = false;
            oXmlDom.load("errors.xml");
           
            //0
表示没有错误
            if (oXmlDom.parseError != 0) {
                var oError = oXmlDom.parseError;
           
                alert("An error occurred:\n
错误代码: "
                      + oError.errorCode + "\n"
                      + "
行数: " + oError.line + "\n"
                      + "
列数: " + oError.linepos + "\n"
                      + "
原因: " + 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.
载入  xmlMozilla    IE  不同的是只提供了一个  load()方法用于载入  xml  文件,没有提供  loadXML()方法用于载入  XML  字符串。同步载入  XML  文件的代码与IE相同:
oXmlDom.async=false;
oXmlDom.load("test.xml");
异步载入稍有不同,因为  Mozilla  并不支持  readyState  属性,并且没有  onreadystatechange  事件,它只有一个  onload  的事件,当载入完成时触发;或者说相当于  IE    readyState  属性等于4的状态。
oXmlDom.onload=function(){
alert("done");
}
oXmlDom.load("test.xml");
要将  XML  字符串解析为  DOM  对象,必须使用  DOMParser  对象:
var oParser=new DOMParser();
var oXmlDom=oParser.parseFromString("<root><child/></root>,"text/xml");
两个参数:要解析的  XML  字符串以及字符串的内容类型(只能为  text/xml  或者  application/xml)。
不过我们可以实现自己的  loadXML  方法:
  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>包括其中的代码解释了错误发生的原因以及位置等信息,我们只有通过正则表达式解析此段代码,提取错误信息。
      var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
          
            //
返回代码的标签名为parsererror,表示错误发生
            if (oXmlDom.documentElement.tagName == "parsererror") {
                reError.test(oXmlDom.xml);
                alert("An error occurred:\n
描述: "
                    + RegExp.$1 + "\n"
                    + "
文件名: " + RegExp.$2 + "\n"
                    + "
行数: " + RegExp.$3 + "\n"
                    + "
列数: " + RegExp.$4 + "\n"
                    + "
原因: " + RegExp.$5);
            }
三,提供一个跨浏览器的  XML DOM  对象解决方案,来自于《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 = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;

            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;
        }
    };
   
     //
定义MozillaloadXML方法  
    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");
    });

}


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:个人博客

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP