您的位置:首页 > Web前端 > JavaScript

javascript解析xml的简单总结

2008-11-13 15:29 369 查看
写在前面的
经常需要使用js来处理xml,在此做一总结.内容比较零散,但相对实用.

将xml文本转换为XMLDOM:

function parseFromFile(addr){

var xmlDoc;

var sourceName = addr;

if (window.XMLHttpRequest) { // FireFox

var xmlDoc = document.implementation.createDocument("","",null);

xmlDoc.async = false;

xmlDoc.load(sourceName);

}else if (window.ActiveXObject) { // IE

try {

xmlDoc = new ActiveXObject("Msxml2.XMLDOM");

xmlDoc.async = false;

xmlDoc.load(sourceName);

} catch (e) {

try {

xmlDoc = new ActiveXObject("Microsoft.XMLDOM");

xmlDoc.async = false;

xmlDoc.load(sourceName);

} catch (e) {}

}

}

return xmlDoc;

}
将xml字符串转换为XMLDOM:

function parseFromString(_value){

var xmlDoc = null;

if(window.XMLHttpRequest){//firefox ..

var oParser = new DOMParser();

xmlDoc = oParser.parseFromString(_value,"text/xml");

}else if(window.ActiveXObject){ //ie

xmlDoc = new ActiveXObject( "Msxml2.DOMDocument");

xmlDoc.loadXML(_value);

}

return xmlDoc;

}
使用js构造XMLDOM:

function createXMLDOM(){

var xmldom = null;

if(window.XMLHttpRequest){//firefox ..

xmldom = document.implementation.createDocument("","",null);

}else if(window.ActiveXObject){ //ie

xmldom = new ActiveXObject( "Msxml2.DOMDocument");

}

return xmldom;

}
关于documentElement:

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

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

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

如xml文件data.xml内容为:

<root>

<test>testValue</test>

</root>

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

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

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

var nodes = root.getElementsByTagName("test");

for(var i=0;i<nodes.length;i++){

//TODO 对有效节点进行操作

}

2

for(var i=0;i<root.childNodes.length;i++){

var node = root.childNodes[i];

if(node.nodeType == 3)//无效的TEXT_NODE

continue;

if(node.nodeType == 1){//需要处理的ELEMENT_NODE

//TODO 对有效节点进行操作

}

}

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

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

data.xml内容

<root>

<test attr="attrValue">testValue</test>

<test><![CDATA[测试cdata]]></test>

<test></test>

</root>

以下是解析过程

var xmlDOM = parseFromFile("t.xml");

var root = xmlDOM.documentElement;

var tests = root.getElementsByTagName("test");

//这里将不进行循环,仅对常用类型节点的解析进行说明

//解析第一个test节点 (解析element_node类型)

var test1 = tests[0];

var test1_attr = test1.getAttribute("attr");//test1 属性

alert(test1_attr);

//注意:test1中的文本,本身是一个text_node

var test1_value = test1.childNodes[0].nodeValue;

alert(test1_value);

//第二个节点 (解析cdata类型)

var test2 = tests[1];

var test2_value = test2.childNodes[0].nodeValue;

alert(test2_value);

//第三个节点 (与第一个节点有什么不同?)

var test3 = tests[3];

alert(test3.childNodes.length);//此时会发现test3的子节点数量为0,原因是当element_node节点下无文本时,将不会建立text_node节点

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属性进行存取.

页面载入时的代码为:

if(document.implementation && document.implementation.createDocument){//当浏览器为firefox时

//alert("firefox...");

Element.prototype.__defineGetter__(

"text",

function(){

return this.textContent;

}

);

Element.prototype.__defineSetter__(

"text",

function(sText){

this.textContent=sText;

}

);

}

使用js构造 xml DOM:

构造一个如data.xml内容的xml DOM

var xmldom = createXMLDOM();

var root = xmldom.createElement("root");

var test1 = xmldom.createElement("test");

test1.setAttribute("attr","testAttr");

var test1Value = xmldom.createTextNode("testValue");

root.appendChild(test1);

test1.appendChild(test1Value);

var test2 = xmldom.createElement("test");

var testCDATA = xmldom.createCDATASection("<test>测试cdata</test>");

root.appendChild(test2);

test2.appendChild(testCDATA);

var test3 = xmldom.createElement("test");

root.appendChild(test3);

alert(root.childNodes[0].text);

alert(root.childNodes[1].text);

alert(root.childNodes[2].text);

后记:
本文例程在ie6.0与firefox2.0中测试通过,对基于webkit核心的浏览器与opera在调用parseFromFile时尚有一些问题.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: