在javascript中操作兼容IE/Firefox浏览器的XMLDOM及扩展[最新]

    一谈起XMLDOM在IE/Firefox浏览器的兼容性,向来都是头疼的问题,也苦了众多前辈在多标准的现状下总结出了颇有价值的代码,以免后人再走弯路。随着javascript和dom版本的不断升级,旧的代码在效率和实现上也适时的出现些变化,达到适应最新同时向下兼容的效果。在javascript中操作xmldom常用的有以下几种场景:

    一、创建XMLDOM对象

 1var _xmlDom = null;
 2    if (!window.DOMParser  && window.ActiveXObject){
 3        var arrXmlDomTypes = ['MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','Microsoft.XMLDOM'];
 4        for(var i = 0;i<arrXmlDomTypes.length;i++){
 5            try{
 6                _xmlDom = new ActiveXObject(arrXmlDomTypes[i]);
 7            }
catch(ex){}//不支持MSXML.XMLDOM对象的IE
 8        }

 9    }
else{// Mozilla browsers have a DOMParser
10        try{
11            if(_xmlDom == null && document.implementation && document.implementation.createDocument){
12                _xmlDom = document.implementation.createDocument("","",null);
13            }

14            isIE = false;
15        }
catch (ex){}
16    }



   二、针对Firefox扩展Document的loadXML方法,使XMLDOM能像在IE中一样使用loadXML加载XML

 1Document.prototype.loadXML = function(sXml){
 2    var oParser= new DOMParser();
 3    var _xmlDom = oParser.parseFromString(sXml, "text/xml");
 4    
 5while(this.firstChild){
 6       this.removeChild(this.firstChild);
 7    }

 8
 9for(var i=0;i<_xmlDom.childNodes.length;i++){
10       var oNewNode = this.importNode(_xmlDo.childNodes[i],true);
11        this.appendChild(oNewNode);
12    }

13}


三、针对Firefox扩展Element的text属性,使XMLDOM能像在IE中一样使用text获取节点的文本内容

1Element.prototype.__defineGetter__("text",function()return this.textContent; });


四、针对Firefox扩展Element的selectNodes,selectSingleNode方法,使XMLDOM能像在IE中一样使用XPath获取节点。在这里我不得不介绍一下网上盛传的版本如下:
 1if(document.implementation.hasFeature("XPath""3.0") )
 2{   
 3   Document.prototype.selectNodes = function(cXPathString, xNode)
 4   {
 5      if!xNode ) { xNode = this; } 
 6      var oNSResolver = this.createNSResolver(this.documentElement)
 7      var aItems = this.evaluate(cXPathString, xNode, oNSResolver, 
 8                   XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
 9      var aResult = [];
10      forvar i = 0; i < aItems.snapshotLength; i++)
11      {
12         aResult[i] =  aItems.snapshotItem(i);
13      }

14      return aResult;
15   }

16
17   Element.prototype.selectNodes = function(cXPathString)
18   {
19      if(this.ownerDocument.selectNodes)
20      {
21         return this.ownerDocument.selectNodes(cXPathString, this);
22      }

23      else{throw "For XML Elements Only";}
24   }
 
25   
26   Document.prototype.selectSingleNode = function(cXPathString, xNode)
27   {
28      if!xNode ) { xNode = this; } 
29      var xItems = this.selectNodes(cXPathString, xNode);
30      if( xItems.length > 0 )
31      {
32         return xItems[0];
33      }

34      else
35      {
36         return null;
37      }

38   }

39      
40   Element.prototype.selectSingleNode = function(cXPathString)
41   {    
42      if(this.ownerDocument.selectSingleNode)
43      {
44         return this.ownerDocument.selectSingleNode(cXPathString, this);
45      }

46      else{throw "For XML Elements Only";}
47   }

48}

看过上面代码片段之后,大家也都会觉得相当麻烦,用了四个方法才扩展了Element的selectNodes,selectSingleNode方法,其实只需要稍作改进就行了,示范如下:

 1Element.prototype.selectSingleNode=function(sXPath){
 2                    var oEvaluator = new XPathEvaluator();
 3                    var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
 4                    if(null != oResult){
 5                        return oResult.singleNodeValue;
 6                    }

 7                    return null;
 8                }

 9                
10                Element.prototype.selectNodes = function(sXPath){
11                    var oEvaluator = new XPathEvaluator();
12                    var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
13                    var aNodes = new Array();
14                    if(null != oResult){
15                        var oElement = oResult.iterateNext();
16                        while(oElement){
17                            aNodes.push(oElement);
18                            oElement = oResult.iterateNext();
19                        }

20                    }

21                    return aNodes;
22                }


综合上面几项,我们可以整理出一套较为完整的片段以备使用:
 1var _xmlDom = null;
 2    if (!window.DOMParser  && window.ActiveXObject){
 3        var arrXmlDomTypes = ['MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','Microsoft.XMLDOM'];
 4        for(var i = 0;i<arrXmlDomTypes.length;i++){
 5            try{
 6                _xmlDom = new ActiveXObject(arrXmlDomTypes[i]);
 7            }
catch(ex){}//不支持MSXML.XMLDOM对象的IE
 8        }

 9    }
else{// Mozilla browsers have a DOMParser
10        try{
11            if(_xmlDom == null && document.implementation && document.implementation.createDocument){
12                _xmlDom = document.implementation.createDocument("","",null);
13
14               Document.prototype.loadXML = function(sXml){
15    var oParser= new DOMParser();
16    var _xmlDom = oParser.parseFromString(sXml, "text/xml");
17    
18    while(this.firstChild){
19    this.removeChild(this.firstChild);
20    }

21
22    for(var i=0;i<_xmlDom.childNodes.length;i++){
23    var oNewNode = this.importNode(_xmlDo.childNodes[i],true);
24        this.appendChild(oNewNode);
25    }

26}

27
28 Element.prototype.__defineGetter__("text",function()return this.textContent; });
29
30Element.prototype.selectSingleNode=function(sXPath){
31                    var oEvaluator = new XPathEvaluator();
32                    var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
33                    if(null != oResult){
34                        return oResult.singleNodeValue;
35                    }

36                    return null;
37                }

38                
39                Element.prototype.selectNodes = function(sXPath){
40                    var oEvaluator = new XPathEvaluator();
41                    var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
42                    var aNodes = new Array();
43                    if(null != oResult){
44                        var oElement = oResult.iterateNext();
45                        while(oElement){
46                            aNodes.push(oElement);
47                            oElement = oResult.iterateNext();
48                        }

49                    }

50                    return aNodes;
51                }

52            }

53            isIE = false;
54        }
catch (ex){}
55    }
    将它包装成function或者分开使用,悉听尊便,希望借此良策以解众博友之困,更欢迎好的建议在这里汇集。
posted on 2008-01-08 11:52  Bean.Hsiang  阅读(3221)  评论(2编辑  收藏  举报