浏览器兼容性改造之为XML支持

1、问题描述

 

1.1、序列化XML

    在IE中,提供xml属性,轻松序列化DOM文档,如下:
    var xml = xmldom.xml;

    为了将XML DOM文档序列化为XML字符串,FireFox 引入了XMLSerializer类型。其他浏览器Opera、Chrome和Safari都支持XMLSerializer,但IE8仍然不支持XMLSerializer。要序列化DOM文档,首先必须创建XMLSerializer的实例,然后将文档传入其中serializeToString()方法,如下:

    var serializer = new XMLSerializer();

    var xml = serializer.serializerToString(xmldom);

 

1.2、加载XML

    IE中的XML文档对象可以加载来自服务器的文件。要加载XML文档必须与页面中运行的JavaScript代码来自同一台服务器。代码如下:
    var xmldom = createDocument();
    xmldom.async = false;
    xmldom.load(“books.xml”);

    Chrome由于安全方面的考虑,不支持load()方法,需要使用AJAX请求方式。

    FireFox同样不支持,须为此添加load()方法。

1.3、解析XML

    IE浏览器下,解析XML字符串,可通过如下方式:
    var xmldom = createDocument();
    xmldom.async = false;
    xmldom.loadXML(“<BOOKS><BOOK><NAME>UML</NAME></BOOK></BOOKS>”);

    为了将XML解析为DOM文档,FireFox引入了DOMPareser类型;后来,Opera也支持该类型。在解析XML之前,首先必须创建一个DOMParser的实例,然后再调用parseFromString()方法。这个方法接受两个参数:要解析的XML字符串和内容类型。返回值为Document的一个实例。如下例子:
    var parse = new DOMParser();
    var xmldom = parser.parseFromString(“<root></root>”, “text/xml”);

1.4、XPath支持

    IE对XPath的支持是内置在XML DOM 文档对象中的。这个节库在每个节点上额外定义了两个方法:selectSingleNode()和selectNodes()。其中,selectSingleNode()方法接受一个XPath模式,在找到匹配节点是返回第一个匹配的节点,如果没有找到匹配的节点就返回null;
    另一个方法selectNodes()也接受一个XPath模式作为参数,但它返回与模式匹配的所有节点的NodeList。
    鉴于IE对XPath功能的支持有限,因此跨浏览器XPath只能保证到IE支持的功能。也就是要在其他使用DOM3级XPath对象的浏览器中,重新创建selectSingleNode()和selectNodes()方法。

 

2、解决方案

    示例代码:

   

if (typeof ActiveXObject === "" && document.implementation.hasFeature("XPath", "3.0")) {

	Document.prototype.readyState = 0;
	Document.prototype.onreadystatechange = null;

	Document.prototype.__changeReadyState__ = function(iReadyState) {
        this.readyState = iReadyState;
        if (typeof this.onreadystatechange == "function") {
            this.onreadystatechange();
        }
    };

    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;
        }
    };
            
    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__();
        this.__changeReadyState__(4);
    };
    
    Document.prototype.load = function (sURL) {
        this.__initError__();
        this.__changeReadyState__(1);
        this.__load__(sURL);
    };    
    
    Document.prototype.__load__ = Document.prototype.load;
    
    Document.prototype.__defineGetter__("xml", function() {
    	return (new XMLSerializer()).serializeToString(this, "text/xml");
    });    

	Node.prototype.__defineGetter__("text", function() {
        var sText = "";
        for (var i = 0; i < this.childNodes.length; i++) {
            if (this.childNodes[i].hasChildNodes()) {
                sText += this.childNodes[i].text;
            } else {
                sText += this.childNodes[i].nodeValue;
            }
        }
        return sText;
    });
	
	Node.prototype.__defineSetter__("text", function(_value) {
		this.textContent = _value;
	});

    Node.prototype.__defineGetter__("xml", function() {
    	return (new XMLSerializer()).serializeToString(this, "text/xml");
    });

    Document.prototype.selectSingleNode = Element.prototype.selectSingleNode = function(xpath) {
        var  x = this.selectNodes(xpath);
        if (!x || x.length < 1) {
        	return   null ;
        }

        return  x[0];
    };

    Document.prototype.selectNodes = Element.prototype.selectNodes = function(xpath) {
    	var xpe = new  XPathEvaluator();
        var nsResolver = xpe.createNSResolver(this.ownerDocument == null ? this.documentElement : this.ownerDocument.documentElement);
        var result = xpe.evaluate(xpath, this, nsResolver, 0, null);
        var found = [];
        var res;
        while(res  =  result.iterateNext()) {
            found.push(res);
        }

        return  found;
    };
    
    HTMLElement.prototype.__defineGetter__( "innerText", function(){
    	var anyString = "";
    	var childS = this.childNodes;
    	for(var i=0; i <childS.length; i++) {
    		if(childS[i].nodeType==1)
    			anyString += childS[i].tagName=="BR" ? '\n' : childS[i].innerText;
    		else if(childS[i].nodeType==3)
    			anyString += childS[i].nodeValue;
    	}
    	return anyString;
    });
    
    HTMLElement.prototype.__defineSetter__( "innerText", function(sText){
    	this.textContent=sText;
    });    
}


 

 

3、参考

    无。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值