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、参考
无。