XmlUtils JS操作XML工具类


Posted in Javascript onOctober 01, 2009

demo用了点extjs的东西,主要是为了打印json数组出来。
js code(XmlUtils.js):

/**/ 
function XmlUtils (config) { 
/*定义私有属性*/ 
this.isIE = !!(window.attachEvent && !window.opera); 
this.init(); 
if(config) { 
this.dataType = config.dataType == 'json' ? 'json' : 'array'; 
if(config.xmlPath) this.loadXml(config.xmlPath); 
} 
} 
XmlUtils.prototype = { 
xmlDoc : null, 
xmlPath : null, 
dataType : null, 
/** 
* 初始化 
*/ 
init : function () { 
if (this.isIE) { 
var activexArr = ["MSXML4.DOMDocument", "MSXML3.DOMDocument", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XmlDom"]; 
for(i=0; i<activexArr.length; i++){ 
try{ 
this.xmlDoc = new ActiveXObject(activexArr[i]); 
}catch(e){} 
} 
} else { 
this.xmlDoc = document.implementation.createDocument("", "", null); 
} 
}, /** 
* 加载xml文件,参数: 
* @param {string} xmlPath:加载的xml文件路径; 
* @return {Object} true 正常加载; false 加载失败 
*/ 
loadXml : function (xmlPath) { 
try { 
this.xmlDoc.async = false; 
this.xmlDoc.load(xmlPath); 
this.xmlPath = xmlPath; 
return true; 
} catch (e) { 
return false; 
} 
}, 
/** 
* 加载XML字符串 
* @param {Object} XMLString 
*/ 
loadXmlString: function(xmlString) { 
if (this.isIE) { 
this.xmlDoc.loadXML(xmlString); 
} else { 
var parser = new DOMParser(); 
this.XMLDoc = parser.parseFromString(xmlString, "text/xml"); 
} 
}, 
/** 
* 判断节点的是否有子节点 
* @param {Object} node 
* @return {Object} 有子节点则返回true,否则返回false 
*/ 
hasChildNodes : function (node) { 
return node.hasChildNodes(); 
}, 
/** 
* 判断节点的是否有属性 
* @param {Object} node 
* @return {Object} 有属性则返回true,否则返回false 
*/ 
hasAttributes : function (node) { 
return (node.attributes.length > 0) ? true : false; 
}, 
/** 
* 判断节点的是否是文本节点,包括带CDATA区段的文本节点 
* @param {Object} node 
* @return {Object} 是文本节点则返回true,否则返回false 
*/ 
isTextNode : function (node) { 
var type = this.getNodeType(node); 
return (type == 3 || type == 4) ? true : false; 
}, 
/** 
* 返回根节点 
* @return {Object} 根节点 
*/ 
getRoot : function () { 
return this.xmlDoc.documentElement; 
}, 
/** 
* 返回节点的第一个子节点,没有参数则返回根节点的第一个子节点 
* @param {Object} node 
* @return {Object} 节点的第一个子节点 
*/ 
getFirstChild : function (node) { 
return node ? node.firstChild : this.getRoot().firstChild; 
}, 
/** 
* 返回节点的最后子节点,没有参数则返回根节点的第一个子节点 
* @param {Object} node 
* @return {Object} 节点的最后一个子节点 
*/ 
getLastChild : function (node) { 
return node ? node.lastChild : this.getRoot().lastChild; 
}, 
/** 
* 返回节点的下一个节点,没有参数则返回根节点的第一个子节点 
* @param {Object} node 
* @return {Object} 节点的下一个节点 
*/ 
getNextNode : function (node) { 
return node ? node.nextSibling : null; 
}, 
/** 
* 返回节点的上一个节点,没有参数则返回根节点的第一个子节点 
* @param {Object} node 
* @return {Object} 节点的上一个节点 
*/ 
getPreviousNode : function (node) { 
return node ? node.previousSibling : null; 
}, 
/** 
* 返回节点的子节点,没有参数则返回null 
* @param {Object} node 
* @return {Object} 节点所有子节点 
*/ 
getChildNodes : function (node) { 
return (node && this.hasChildNodes(node)) ? node.childNodes : null; 
}, 
/** 
* 返回节点的父节点,没有参数则返回null 
* @param {Object} node 
* @return {Object} 节点父节点 
*/ 
getParentNode : function (node) { 
return node ? node.parentNode : null; 
}, 
/** 
* 根据节点名返回节点数组文本值,参数: 
* @param {string或object} nodeName:节点名称; 
* @return {object} 节点存在返回节点数组;节点不存在则返回null。 
*/ 
getNodesTextByName : function (nodeNames) { 
return nodeNames ? (this.dataType == 'json' ? this.getJsonNodesTextByName(nodeNames) : this.getArryNodesTextByName(nodeNames)) : null; 
}, 
/** 
* 根据节点名返回节点普通数组文本值,参数: 
* @param {string或object} nodeName:节点名称; 
* @return {object} 节点存在返回节点普通数组。 
*/ 
getArryNodesTextByName : function (nodeNames) { 
var rs = []; 
//返回普通数组格式 
switch (typeof(nodeNames)) { 
case 'string': 
var nodes = this.getNodesByTagName(nodeNames); 
for (var i = 0; i < nodes.length; i++) { 
rs.push(nodes[i].text); 
} 
break; 
case 'object': 
var subRs; 
var nodes; 
for (var i = 0; i < nodeNames.length; i++) { 
nodes = this.getNodesByTagName(nodeNames[i]); 
subRs = []; 
for (var j = 0; j < nodes.length; j++) { 
subRs.push(nodes[j].text); 
} 
rs.push(subRs); 
} 
break; 
} 
return rs; 
}, 
/** 
* 根据节点名返回节点JSON数组文本值,参数: 
* @param {string或object} nodeName:节点名称; 
* @return {object} 节点存在返回节点JSON数组;节点不存在则返回null。 
*/ 
getJsonNodesTextByName : function (nodeNames) { 
var rs = null; 
//返回JSON数组格式 
switch (typeof(nodeNames)) { 
case 'string': 
eval('rs = {' + nodeNames + ':[]}'); 
var nodes = this.getNodesByTagName(nodeNames); 
for (var i = 0; i < nodes.length; i++) { 
eval('rs.' + nodeNames + '.push({' + nodeNames + i + ': nodes[i].text})'); 
} 
break; 
case 'object': 
rs = {}; 
var nodes; 
for (var i = 0; i < nodeNames.length; i++) { 
eval('rs.' + nodeNames[i] + '=[]'); 
nodes = this.getNodesByTagName(nodeNames[i]); 
for (var j = 0; j < nodes.length; j++) { 
eval('rs.' + nodeNames[i] + '.push({' + nodeNames[i] + j + ': nodes[j].text})'); 
} 
} 
break; 
} 
return rs; 
}, 
/** 
* 根据节点属性得到节点,参数: 
* @param {String} key:属性名,默认是id 
* @param {String} value:属性值 
* @return {String} 符合条件的节点数组。 
*/ 
getNodesByAttribute : function (key, value) { 
key = key ? key : 'id'; 
value = value ? value : ''; 
return id ? this.xmlDoc.getElementById(id) : null; 
}, 
/** 
* 根据节点名得到节点,参数: 
* @param {string} tagName:节点名称 
* @return {string} 指定节点名字的和位置的节点或节点数组。 
*/ 
getNodesByTagName : function (tagName) { 
return tagName ? this.xmlDoc.getElementsByTagName(tagName) : null; 
}, 
/** 
* 根据节点路径返回第index个节点,参数: 
* @param {string} xPath:节点路径 
* @param {number}index:要索引的位置,为空或0则返回所有查找到的节点。 
* @return {string} 指定节点名字的和位置的节点或节点数组。 
*/ 
getNodesByXpath : function (xPath, index) { 
if (!xPath) return null; 
var nodes = this.xmlDoc.selectNodes(xPath); 
var len = nodes.length; 
if(!index || index > len || index < 0) return nodes; 
for(var i=0; i<len; i++){ 
if(i == index - 1) return nodes[i]; 
} 
}, 
/** 
* 得到指定节点文本,参数: 
* @param {object} node:节点 
* @return {string} 节点文本,为空则返回null 
*/ 
getText : function (node) { 
return node ? node.text : null; 
}, 
/** 
* 得到指定节点名称,参数: 
* @param {object} node:节点 
* @return {string} 节点名称,为空则返回null 
*/ 
getTagName : function (node) { 
return node ? node.nodeName : null; 
}, 
/** 
* 返回节点类型,参数: 
* @param {object} node:节点 
* @return {string} 节点类型,为空则返回null 
* 1-element 
* 2-attribute 
* 3-text 
* 4-cdata 
* 5-entity reference 
* 6-entity 
* 7-pi (processing instruction) 
* 8-comment 
* 9-document 
* 10-document type 
* 11-document fragment 
* 12-notation 
*/ 
getNodeType : function (node) { 
return node ? node.nodeType : null; 
}, 
/** 
* 创建节点,参数: 
* @param {string} nodeName:节点名称,必填 
* @param {string} text:节点文本,可为空 
* @param {Object} attributes:属性值-JSON数组,可为空,例:{id:'id001',name:'name001'} 
* @param {Object} node:要增加子节点的节点,为空则返回新建的节点 
* @param {Boolean} cdata:是否生成带有CDATA区段的节点,true:生成,false:不生成 
* @return {Object} 创建的节点,有异常则返回null 
*/ 
createNode: function(nodeName, text, attributes, node, cdata) { 
if (this.isIE) { 
//创建子接点 
var childNode = this.xmlDoc.createElement(nodeName); 
//创建文本节点 
var textNode = cdata == true ? this.xmlDoc.createCDATASection(text) : this.xmlDoc.createTextNode(text); 
childNode.appendChild(textNode); 
//添加属性 
for (var i in attributes) { 
this.createAttribute(childNode,i,attributes[i]); 
}; 
return node ? node.appendChild(childNode) : childNode; 
} else { 
alert('FF创建节点再说.'); 
return null; 
} 
}, 
/** 
* 创建带CDATA区段的节点,参数: 
* @param {string} nodeName:节点名称,必填 
* @param {string} text:节点文本,可为空 
* @param {Object} attributes:属性值-JSON数组,可为空,例:{id:'id001',name:'name001'} 
* @param {Object} node:要增加子节点的节点,为空则返回新建的节点 
*/ 
createCDATANode: function(nodeName, text, attributes, node) { 
this.createNode(nodeName, text, attributes, node, true); 
}, 
/** 
* 创建节点属性,参数: 
* @param {Object} node:节点,必填 
* @param {String} key:属性名,必填 
* @param {Object} value:属性值,必填 
* @param {Object} node:返回新增属性的节点 
* @return {Object} 增加属性的节点,有异常则返回null 
*/ 
createAttribute: function(node, key, value) { 
if (this.isIE) { 
if(!key) return; 
var attr = this.xmlDoc.createAttribute(key); 
attr.value = value ? value : ""; 
node.setAttributeNode(attr); 
return node; 
} else { 
alert('FF创建节点再说.'); 
return node; 
} 
return null; 
}, 
/** 
* 把节点加到根节点上,参数: 
* @param {Object} node:节点 
* @return {Object} 有异常则返回null 
*/ 
addNodeToRoot: function(node) { 
if(!node) return null; 
this.getRoot().appendChild(node); 
return node; 
}, 
/** 
* 把节点加到另外节点上,参数: 
* @param {Object} node:节点 
*/ 
addNode: function(node,childNode) { 
return (node && childNode) ? node.appendChild(childNode) : false; 
}, 
/** 
* 从父节点移除节点自身,参数: 
* @param {Object} newNode:要替换的节点 
* @param {Object} oldNode:要被替换的节点 
*/ 
replaceChild: function(newNode, oldNode) { 
var parentNode = oldNode.parentNode; 
if(!newNode || !oldNode || !parentNode) return; 
parentNode.replaceChild(newNode, oldNode); 
}, 
/** 
* 从父节点移除节点自身,参数: 
* @param {Object} node:要移除的节点 
*/ 
removeChild: function(node) { 
if(!node || !node.parentNode) return; 
node.parentNode.removeChild(node); 
}, 
/** 
* 移除节点的所有子节点,参数: 
* @param {Object} node:父节点 
*/ 
removeChildNodes: function(node) { 
if (node && this.hasChildNodes(node)) { 
var childNodes = node.childNodes; 
for(var i = 0; i < childNodes.length; i++) { 
node.removeChild(childNodes[0]); 
} 
} 
}, 
/** 
* 设置节点属性值,不存在则新建,参数: 
* @param {Object} node:要设置的节点 
* @param {String} key:要设置的属性名 
* @param {String} value:要设置的属性值 
*/ 
setAttribute: function(node, key, value) { 
this.createAttribute(node, key, value); 
}, 
/** 
* 设置文本节点的文本,参数: 
* @param {Object} node:要设置的节点 
* @param {String} text:要设置的文本 
*/ 
setText: function(node, text) { 
if(this.isTextNode(node)) node.text = text; 
}, 
/** 
* 在文本节点后面追加文本,参数: 
* @param {Object} node:要设置的节点 
* @param {String} text:要设置的文本 
*/ 
appendText: function(node, text) { 
if(this.isTextNode(node)) node.appendData(text); 
}, 

/** 
* 输出xml,为空则输出根节点文本,参数: 
* @param {Object} node:要输出的节点 
*/ 
toString: function(node) { 
node = node ? node : this.xmlDoc.documentElement; 
if (typeof node == 'string') return node; 
return this.isIE ? node.xml : new XMLSerializer().serializeToString(node); 
} 
}

测试的xml文件(book.xml):
<?xml version="1.0" encoding="utf-8"?> 
<root> 
<book> 
<name>西游记</name> 
<author>吴承恩</author> 
</book> 
<book> 
<name>红楼梦</name> 
<author>曹雪芹</author> 
</book> 
<book> 
<name>三国演义</name> 
<author> 
<name>施耐庵</name> 
<sex>男</sex> 
</author> 
</book> 
<book> 
<name>水浒传</name> 
<author>罗贯中</author> 
</book> 
</root>

html code (test.html):
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<script language="JavaScript" type="text/javascript" src="../Ext/ext-base.js" ><!-- // --></script> 
<script language="JavaScript" type="text/javascript" src="../Ext/ext-all.js" ><!-- 
// --></script> 
<title>测试xml</title> 
<script src="XmlUtils.js"></script> 
</head> 
<body> 
<div id='xmlOpTest'></div> 
</body> 
<script type="text/javascript"><!-- 
/** 
* config参数:xmlPath文件地址;dataType数据格式-json或arry,默认为array。 
*/ 
var xmlUtils = new XmlUtils({xmlPath:"book.xml",dataType:'json'}); 
alert(xmlUtils.toString()); 
var rs = xmlUtils.getNodesTextByName(['name','author']); 
//把上面的dataType改为array或者不为json此处就能得到值 
document.getElementById('xmlOpTest').innerHTML += '<br/>取得所有的文本节点的数组: '+rs + '<br/>'; 
//这里用了Ext的json解析工具 Ext.encode这个方法是把json对象转换为字符串。Ext.decode则相反,把json格式的字符串转换为json对象数组 
document.getElementById('xmlOpTest').innerHTML += '<br/>取得所有的文本节点的JSON数组: '+Ext.encode(rs)+'<br/>'; 
var root = xmlUtils.getRoot(); 
xmlUtils.createNode('publish', '中国电力出版社',{id:'id0001'},root); 
xmlUtils.createCDATANode('publish', '中国&电力出版社',{},root); 
//设置属性 
xmlUtils.setAttribute(root,'testId','test'); 
//修改属性 
xmlUtils.setAttribute(root,'testId','test0000000000'); 
alert(xmlUtils.toString(root)); 
xmlUtils.removeChild(xmlUtils.getNodesByXpath('//root/publish')[0]); 
alert(xmlUtils.toString(root)); 
node = xmlUtils.getFirstChild(); 
document.getElementById('xmlOpTest').innerHTML += '<br/>判断是否有子节点: '+xmlUtils.hasChildNodes(node) + ' ------ 判断是否有属性:';//+ xmlUtils.hasAttributes(node) +'<br/>'; 
document.getElementById('xmlOpTest').innerHTML += '<br/>得到节点的第一个节点: '+xmlUtils.getTagName(node) + "---" + xmlUtils.getText(node) +' ======== 节点类型:' + xmlUtils.getNodeType(node) + '<br/>'; 
node = xmlUtils.getNextNode(node); 
document.getElementById('xmlOpTest').innerHTML += '<br/>得到节点的第一个节点下一个节点: '+xmlUtils.getTagName(node) + "---" + xmlUtils.getText(node) +'<br/>'; 
node = xmlUtils.getLastChild(); 
document.getElementById('xmlOpTest').innerHTML += '<br/>得到节点的最后一个节点: '+xmlUtils.getTagName(node) + "---" + xmlUtils.getText(node) +'<br/>'; 
node = xmlUtils.getPreviousNode(node); 
document.getElementById('xmlOpTest').innerHTML += '<br/>得到节点的最后一个前一个节点: '+xmlUtils.getTagName(node) + "---" + xmlUtils.getText(node) +'<br/>'; 
node = xmlUtils.getParentNode(node); 
document.getElementById('xmlOpTest').innerHTML += '<br/>得到节点的父节点: '+ xmlUtils.toString(node) +'<br/>'; 
var nodes = xmlUtils.getChildNodes(); 
document.getElementById('xmlOpTest').innerHTML += '<br/>得到节点的所有子节点: '+xmlUtils.toString(nodes)+'<br/>'; 
node = xmlUtils.getNodesByXpath('//root/book/name',2); 
document.getElementById('xmlOpTest').innerHTML += '<br/>根据xPath得到节点名称和文本值: '+xmlUtils.getTagName(node) + "---" + xmlUtils.getText(node)+'<br/>'; 
node = xmlUtils.getNodesByXpath('//root/book/author'); 
document.getElementById('xmlOpTest').innerHTML += '<br/>根据xPath得到节点名称和文本值: '+xmlUtils.getTagName(node[0]) + "---" + xmlUtils.getText(node[0])+'<br/>'; 
//得到修改后的文本节点 
node = xmlUtils.getNodesByXpath('//root/publish',1); 
node = xmlUtils.getFirstChild(node); 
document.getElementById('xmlOpTest').innerHTML += '<br/>修改文本值前节点文本: '+xmlUtils.getText(node); 
xmlUtils.setText(node,"西游记后传"); 
document.getElementById('xmlOpTest').innerHTML += '-----修改文本值后节点文本: '+xmlUtils.getText(node); 
xmlUtils.appendText(node,"之测试"); 
document.getElementById('xmlOpTest').innerHTML += '-----追加文本值后节点文本: '+xmlUtils.getText(node) + "<br/>"; 
// --></script> 
</html>

上面的文件都上传了,正在审核中,等审核通过了我会发到这里的。
Javascript 相关文章推荐
让您的菜单不离网站
Oct 03 Javascript
StringTemplate遇见jQuery冲突的解决方法
Sep 22 Javascript
js document.write()使用介绍
Feb 21 Javascript
javascript中expression的用法整理
May 13 Javascript
浅谈EasyUI中编辑treegrid的方法
Mar 01 Javascript
纯javascript实现简单下拉刷新功能
Mar 13 Javascript
jQuery实现鼠标经过图片变亮其他变暗效果
May 08 Javascript
AngularJS自定义服务与fliter的混合使用
Nov 24 Javascript
JavaScript中Math对象的方法介绍
Jan 05 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
Jan 22 Javascript
通过jsonp获取json数据实现AJAX跨域请求
Jan 22 Javascript
Element-ui Layout布局(Row和Col组件)的实现
Dec 06 Vue.js
PPK 谈 JavaScript 的 this 关键字 [翻译]
Sep 29 #Javascript
一个JS小玩意 几个属性相加不能超过一个特定值.
Sep 29 #Javascript
IE FF OPERA都可用的弹出层实现代码
Sep 29 #Javascript
javascript 表单验证常见正则
Sep 28 #Javascript
javascript 页面划词搜索JS
Sep 28 #Javascript
jquery 模式对话框终极版实现代码
Sep 28 #Javascript
javascript的onchange事件与jQuery的change()方法比较
Sep 28 #Javascript
You might like
非常好用的Zend Framework分页类
2014/06/25 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
2016/01/22 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
thinkPHP框架RBAC实现原理分析
2019/02/01 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
2019/12/01 PHP
基于node.js的快速开发透明代理
2010/12/25 Javascript
js 获取、清空input type=&quot;file&quot;的值(示例代码)
2013/12/24 Javascript
多种方法实现load加载完成后把图片一次性显示出来
2014/02/19 Javascript
js实现通用的微信分享组件示例
2014/03/10 Javascript
JavaScript数值转换的三种方式总结
2014/07/31 Javascript
JavaScript中检查对象property的存在性方法介绍
2014/12/30 Javascript
javascript作用域问题实例分析
2015/07/13 Javascript
JS简单实现表格排序功能示例
2016/12/20 Javascript
Angular.js中定时器循环的3种方法总结
2017/04/27 Javascript
将angular.js项目整合到.net mvc中的方法详解
2017/06/29 Javascript
react-native-video实现视频全屏播放的方法
2018/03/19 Javascript
Node.js 使用jade模板引擎的示例
2018/05/11 Javascript
浅析node.js的模块加载机制
2018/05/25 Javascript
使用javascript做在线算法编程
2018/05/25 Javascript
JSON基本语法及与JavaScript的异同实例分析
2019/01/04 Javascript
js设置默认时间跨度过程详解
2019/07/17 Javascript
如何在微信小程序中存setStorage
2019/12/13 Javascript
[49:59]KG vs Mineski 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python实现获取客户机上指定文件并传输到服务器的方法
2015/03/16 Python
利用Celery实现Django博客PV统计功能详解
2017/05/08 Python
python机器学习之神经网络(三)
2017/12/20 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
在python中list作函数形参,防止被实参修改的实现方法
2020/06/05 Python
python实现文件分片上传的接口自动化
2020/11/19 Python
Python实现王者荣耀自动刷金币的完整步骤
2021/01/22 Python
如何高效率的查找一个月以内的数据
2012/04/15 面试题
财务负责人任命书
2014/06/06 职场文书
试用期旷工辞退通知书
2015/04/17 职场文书
2016年学校安全教育月活动总结
2016/04/06 职场文书
小学三年级作文之写景
2019/11/05 职场文书
Java实现房屋出租系统详解
2021/10/05 Java/Android