一谈起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 }
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}
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 for( var 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}
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 for( var 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 }
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或者分开使用,悉听尊便,希望借此良策以解众博友之困,更欢迎好的建议在这里汇集。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 }