XML的全称Extensible Markup Language,叫做可扩展标记语言,它和超文本标记语言很像,但是又有些不同
- XML设计目的是传输数据,而不是显示数据。
- 它的标签被预定义,你需要自己进行定义
- 它被设计为具有自我描述性
- 它是W3C的推荐标准
它和超文本标记语言为不同的目的而设计,XML被设计用来传输和存储数据,其焦点是数据的内容,而超文本标记语言被设计来显示数据,其焦点是数据的外观
XML的创建方法在IE和其它浏览器中有很大的不同,IE提供了一个ActiveX()对象来创建XML,这个对象不仅要浏览器支持 还需要windows系统支持,而这一方法对其它浏览器是不适用的
IE创建XML
//创建XMLDOM对象
var xmlDom = new ActiveXObject('MSXML2.DOMDocument');
alert(xmlDom);
下面给出比较推荐的创建方法
function createXMLDOM(){
var version = [
'MSXML2.DOMDocument6.0',
'MSXML2.DOMDocument3.0',
'MSXML2.DOMDocument'
];
for (var i = 0; i < version.length; i++) {
try{
var xmlDom= new ActiveXObject(version[i]);
return xmlDom;
}catch(e){
//跳过 即如果第一个不支持不抛出错误而是跳过去执行第二个...
}
}
throw new Error('你的系统或浏览器不支持MSXML库!'); //其它不支持的浏览器抛出错误
}
在创建XML DOM之后 我们还需要载入XML,IE提供了两种载入方法,和.xml属性来序列化
1. loadXML()方法XML字符串
2. load()方法XML外部文件
//第一种方法
//因为XML和XHTML一样,都是通过DOM操作的,所以之前的都可以用到
var xmlDom = createXMLDOM(); //这里我直接调用的上文的创建方法
xmlDom.loadXML('<root><user>Fighting!</user></root>'); //<root></root>是根节点 必须要有 其它自己定义
alert(xmlDom.xml) //序列化XML,即打印字符串
var user = xmlDom.getElementsByTagName('user')[0]; //ps:XML不是通过document来获取节点的 ,而是通过你创建的对象来获取
alert(user.nodeType);
alert(user.tagName);//user
//alert(user.innerHTML) //无效,XML遵循的是标准DOM,而innerHTML不是标准DOM
alert(user.firstChild.nodeValue); //Fighting! 有效
//第二种方法
var xmlDom = createXMLDOM();
xmlDom.load('index.xml');//加载外部XML文件 这里的外部文件为index.xml 我就没有显示了
我们还可以创建XML节点
var xmlDom = createXMLDOM();
xmlDom.load('index.xml');
var aaa = xmlDom.createElement('aaa'); //创建新的节点
var root = xmlDom.getElementsByTagName('root')[0];
root.appendChild(aaa);
var aaaText = xmlDom.createTextNode('Hello World'); //创建节点的文本
aaa.appendChild(aaaText);
alert(xmlDom.xml)
那么在IE的服务器端是如何同步使用和异步使用XML的呢?
load()方法是服务器端XML的,并且限制服务器上的XML文件,在载入的时候有两种模式:同步和异步。
所谓同步就是在XML没有加载完成之前,代码不会继续,知道完成加载了XML再返回。好处就是简单方便,缺点就是如果加载的数据停止响应或延迟太久的话,浏览器会一直堵塞而造成假死状态。
异步就是在加载XML的时候,Javascript会把任务丢给浏览器后台处理,不会堵塞,但要readystatechange事件使用,来判断是否加载完成。
var xmlDom = createXMLDOM();
xml.async = true; //默认是异步,true表示异步,false表示同步
xmlDom.onreadystatechange = function(){ //这个方法必须放在load()的前面
if(xmlDom.readyState==4){ //4表示完全加载
if(xmlDom.parseError.errorCode==0){ //0表示没有错误
alert(xmlDom.xml);
}else{
throw new Error('错误代号:'+xmlDom.parseError+
'\n错误代号:'+xmlDom.parseError.errorCode+
'\n错误解释:'+xmlDom.parseError.reason);
}
}
}
xmlDom.load('index.xml');
//alert(xmlDom.xml);
W3C的DOM2级创建XML DOM
var xmlDom = document.implementation.createDocument('','root','null');////第一个参数为命名空间 第二个参数为根标签名 第三个参数为文档声明
alert(xmlDom);
然而DOM2级不支持loadXML()方法来载入XML的,只支持load()方法,并且load()方法只有firefox和新版的opera浏览器支持 ,其它浏览器不支持;并且DOM2级没有.xml属性来序列化的
所以DOM2级提供了DOMParser类型来创建XML DOM对象,并且提供XMLSerializer类型来帮助序列化XML字符串
var xmlParser = new DOMParser(); //创建DOMParser 对象
var xmlStr = '<root><user>Fighting!</user></root>';
var xmlDOM = xmlParser.parseFromString(xmlStr,'text/xml'); //创建XML DOM
alert(xmlDom);
var serializer = new XMLSerializer();
var xml = serializerToString(xmlDom);
var error = xmlDom.getElementsByTagName('parsererror'); //如果出现错误会有parererror标签,所以可以通过这个标签进行错误处理
if(error.length==0){ //错误处理 lenth==0说明没有错误
alert(xml);
}else{
throw new Error('错误信息:'+errors[0].textContent);
}
最后结合IE的方法和DOM2级的方法,我们需要跨浏览器来处理XML
跨浏览器我们需要考虑几个问题:
1.load()只有 IE,Firefox,Opera支持,所以无法实现跨浏览器
2.获取XML DOM 对象的问题,先判断比较先进的DOM2级的 ,然后再判断落后的IE,
3.针对不同的IE和DOM2级要使用不同的序列化
4.针对不同的要有不同的报错机制
所以终极版本如下:
//跨浏览器返回XML DOM对象
function getXMLDOM(xmlStr){
var xmlDom = null;
if (typeof window.DOMParser!='undefined') { //不等于undefined说明是W3C浏览器
xmlDom = (new DOMParser()).parseFromString(xmlStr,'text/xml');
var errors = xmlDom.getElementsByTagName('parsererror');
if (errors.length>0) {
throw new Error('错误有信息:'+errors[0].textContent);
}
}else if(typeof window.ActiveXObject!='undefined'){ //IE浏览器
var version = [
'MSXML2.DOMDocument6.0',
'MSXML2.DOMDocument3.0',
'MSXML2.DOMDocument'
];
for (var i = 0; i < version.length; i++) {
try{
var xmlDom= new ActiveXObject(version[i]);
}catch(e){
//跳过 即如果第一个不支持不抛出错误而是跳过去执行第二个...
}
}
xmlDom.loadXML(xmlStr);
if (xmlDom.parseError!=0) { //不等于0说明有错误
throw new Error('错误有信息:'+xmlDom.parseError.reason);
}
return xmlDom;
}else{
throw new Error('你的系统或浏览器不支持XML DOM对象'); //其它不支持的浏览器抛出错误
}
return xmlDom;
}
//跨浏览器序列化XML
function serializerXML(){
var xml= '';
if (typeof window.XMLSerializer!='undefined') { //w3c
xml=(new XMLSerializer()).serializeToString(xmlDom);
}else if(typeof xmlDom.xml!='undefined'){
xml=xmlDom.xml;
}
return xml;
}
var xmlStr='<root><user>Lee</user></root>';
var xmlDom = getXMLDOM(xmlStr);
// alert(xmlDom); //返回XML DOM对象
alert(serializerXML(xmlDom)); //序列化
//PS:为了兼容浏览器 我们没有采用外部加载xml文件的方式 而是内部写入的方式