javascript解析xml的简单总结

来源:互联网 发布:互联网 大数据 论文 编辑:程序博客网 时间:2024/05/20 22:02

写在前面的
    经常需要使用js来处理xml,在此做一总结.内容比较零散,但相对实用.


将xml文本转换为XMLDOM:

  1.     function parseFromFile(addr){
  2.         var xmlDoc;
  3.         var sourceName = addr;
  4.         if (window.XMLHttpRequest) { // FireFox
  5.             var xmlDoc = document.implementation.createDocument("","",null);
  6.             xmlDoc.async = false;
  7.             xmlDoc.load(sourceName);
  8.         }else if (window.ActiveXObject) { // IE
  9.             try {
  10.                 xmlDoc = new ActiveXObject("Msxml2.XMLDOM");
  11.                 xmlDoc.async = false;
  12.                 xmlDoc.load(sourceName);
  13.             } catch (e) {
  14.                 try {
  15.                     xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  16.                     xmlDoc.async = false;
  17.                     xmlDoc.load(sourceName);
  18.                 } catch (e) {}
  19.             }
  20.         }
  21.         return xmlDoc;
  22.     }
将xml字符串转换为XMLDOM:

  1.     function parseFromString(_value){
  2.         var xmlDoc = null;
  3.         if(window.XMLHttpRequest){//firefox .. 
  4.             var oParser = new DOMParser();
  5.             xmlDoc = oParser.parseFromString(_value,"text/xml");
  6.             
  7.         }else if(window.ActiveXObject){ //ie
  8.             xmlDoc = new ActiveXObject( "Msxml2.DOMDocument");
  9.             xmlDoc.loadXML(_value);
  10.         }
  11.         
  12.         return xmlDoc;
  13.     }
使用js构造XMLDOM:

  1.     function createXMLDOM(){
  2.         var xmldom = null;
  3.         if(window.XMLHttpRequest){//firefox ..
  4.             xmldom = document.implementation.createDocument("","",null);
  5.         }else if(window.ActiveXObject){ //ie
  6.             xmldom = new ActiveXObject( "Msxml2.DOMDocument");
  7.         }
  8.         return xmldom;
  9.     }
关于documentElement:

    可以很方便的得到xml DOM文档的根节点

  1.     var root = xmlDOM.documentElement;//xmlDOM为已得到的DOM文档
如何使用childNodes遍历节点:

    通过childNodes来取得子节点,但ie(trident核心)与firefox(gecko核心)对childNodes的解释有些许不同.经常在ie下工作正常的脚本,在其他浏览器中运行会出现错误,往往因为这个原因.


    如xml文件data.xml内容为:
  1.     <root>
  2.         <test>testValue</test>
  3.     </root>

    var root = parseFromFile("test.xml");

    ie中,root.childNodes.length == 3
    firefox中,root.childNodes.length == 5


    原因是firefox将一些无效的换行空格也作为文本节点进行计算
    为保证在ie与ff中的一致操作,解决方法大致有以下两个:
    1    

  1.         var nodes = root.getElementsByTagName("test");
  2.         for(var i=0;i<nodes.length;i++){
  3.             //TODO 对有效节点进行操作
  4.         }

    2    

  1.         for(var i=0;i<root.childNodes.length;i++){
  2.             var node = root.childNodes[i];
  3.             if(node.nodeType == 3)//无效的TEXT_NODE 
  4.                 continue;
  5.             if(node.nodeType == 1){//需要处理的ELEMENT_NODE
  6.                 //TODO 对有效节点进行操作
  7.             }
  8.         }

关于节点类型nodeType:
    常用的nodeType大致三种:
    1:ELEMENT_NODE
    3:TEXT_NODE
    4:CDATA_SECTION_NODE

    接下来用一个例子来说明如何解析节点

    data.xml内容

  1.     <root>
  2.         <test attr="attrValue">testValue</test>
  3.         <test><![CDATA[测试cdata]]></test>
  4.         <test></test>
  5.     </root>

    以下是解析过程

  1.     var xmlDOM = parseFromFile("t.xml");    
  2.     var root = xmlDOM.documentElement;
  3.     var tests = root.getElementsByTagName("test");
  4.     //这里将不进行循环,仅对常用类型节点的解析进行说明
  5.     //解析第一个test节点  (解析element_node类型)
  6.     var test1 = tests[0];
  7.     var test1_attr = test1.getAttribute("attr");//test1 属性
  8.     alert(test1_attr);    
  9.     //注意:test1中的文本,本身是一个text_node
  10.     var test1_value = test1.childNodes[0].nodeValue;
  11.     alert(test1_value);
  12.     //第二个节点 (解析cdata类型)
  13.     var test2 = tests[1];
  14.     var test2_value = test2.childNodes[0].nodeValue;
  15.     alert(test2_value);
  16.     //第三个节点 (与第一个节点有什么不同?)
  17.     var test3 = tests[3];
  18.     alert(test3.childNodes.length);//此时会发现test3的子节点数量为0,原因是当element_node节点下无文本时,将不会建立text_node节点
  19.     var test3_value = ""

    test1与test3虽然看起来结构相同,但由于其xml DOM的结构并不相同,因此处理的时候需要注意区分
    一种办法是先判断节点的childNodes的长度,不为0时可使用test1的方式进行处理,否则使用test3的方式
    另一种方法是通过判断浏览器,当为firefox时,使用test3.textContent属性进行存取,当为ie时,使用test3.text属性进行存取

    以上两种方法都过于繁琐,当xml DOM节点比较多时,将产生比较多的冗余代码,那是否存在更为优雅的办法?答案是肯定的.
    在页面载入时,在firefox中,通过Element的原型来创建text属性,从而达到在ie与firefox使用统一的text属性进行存取.

    页面载入时的代码为:

  1.     if(document.implementation && document.implementation.createDocument){//当浏览器为firefox时
  2.         //alert("firefox...");
  3.         Element.prototype.__defineGetter__(
  4.             "text",
  5.             function(){
  6.                 return this.textContent;
  7.             }
  8.         );
  9.         
  10.         Element.prototype.__defineSetter__(
  11.             "text",
  12.             function(sText){
  13.               this.textContent=sText;
  14.             }
  15.         );
  16.         
  17.     }

使用js构造 xml DOM:
    
    构造一个如data.xml内容的xml DOM

  1.     var xmldom = createXMLDOM();
  2.     var root = xmldom.createElement("root");
  3.     var test1 = xmldom.createElement("test");
  4.     test1.setAttribute("attr","testAttr");
  5.     var test1Value = xmldom.createTextNode("testValue");
  6.     root.appendChild(test1);
  7.     test1.appendChild(test1Value);
  8.     var test2 = xmldom.createElement("test");
  9.     var testCDATA = xmldom.createCDATASection("<test>测试cdata</test>");
  10.     root.appendChild(test2);
  11.     test2.appendChild(testCDATA);
  12.     var test3 = xmldom.createElement("test");
  13.     root.appendChild(test3);
  14.     alert(root.childNodes[0].text);
  15.     alert(root.childNodes[1].text);
  16.     alert(root.childNodes[2].text);

后记:
    本文例程在ie6.0与firefox2.0中测试通过,对基于webkit核心的浏览器与opera在调用parseFromFile时尚有一些问题.

原创粉丝点击