分享一个js解析xml的通用函数,终于体会到了只要获得对象一切皆有可能!面向对象就是不一样啊
废话少说,直接看代码吧,已经加了很详细的注释了,看不懂就先学习学习再来看了!
最近看了些书,说浏览器判断是非常糟糕的设计思想,因为除了ie和火狐外大多数浏览器都会伪装自己为ie
而当新的浏览器出来的时候代码就不能自动适应了(例如最近出来的google浏览器),所以解决的最终办法是用功能检测模型去执行代码,而且把标准代码先判断执行,这样不够是什么浏览器都可以兼容了,而且新出来的浏览器只要支持这个功能就可以执行这个代码,这样就不用修改代码来适应不同浏览器了。
//把浏览器判断换成 功能检测模型,而且把标准代码先判断执行,更加合适和具有兼容性
//由于直接执行不兼容的代码会报错,所以采用try catch解决
parseXML.js
var XMLJS = function(){}; XMLJS.apply = function(o, c, defaults){ if(defaults){ // no "this" reference for friendly out of scope calls XMLJS.apply(o, defaults); } if(o && c && typeof c == 'object'){ for(var p in c){ o[p] = c[p]; } } return o; }; XMLJS.apply(XMLJS, { docObjs : new Array, /** * 初始化xml对象文件连接池 */ initDocs : function(count) { if(count == null) count = 3; for(var i = 0; i < count; i++) { XMLJS.docObjs[i] = new Object; //把浏览器判断换成代码判断,而且把标准代码先判断执行,更加合适和具有兼容性 //由于直接执行不兼容的代码会报错,所以采用try catch解决 try { XMLJS.docObjs[i].doc = new DOMParser(); XMLJS.docObjs[i].doc.async = false; XMLJS.docObjs[i].free = true; } catch(e) { XMLJS.docObjs[i].doc = new ActiveXObject('Microsoft.XMLDOM'); XMLJS.docObjs[i].doc.async = false; XMLJS.docObjs[i].free = true; } } }, /** * 获得空闲xml文件docObj对象 */ getFreeDocObj : function () { var docObj = null; for(var i = 0; i < XMLJS.docObjs.length; i++) { if(XMLJS.docObjs[i].free) { XMLJS.docObjs[i].free = false; docObj = XMLJS.docObjs[i]; break; } } return docObj; }, /** * 解析xml */ parseXML : function (xmlContent) { var docObj = XMLJS.getFreeDocObj(); try { var XmlDom = docObj.doc.parseFromString(xmlContent,"text/xml"); docObj.free = true; return XmlDom; } catch(e) { docObj.doc.loadXML (xmlContent);//解析字符串不能用load必须用loadXML.(load解析载入文档的) var doc = docObj.doc; docObj.free = true; return doc; } }, /** * 解析xml */ parseXML2 : function (xmlContent) { var xmlDoc; try { xmlDoc = new DOMParser(); var XmlDom = xmlDoc.parseFromString(xmlContent,"text/xml"); return XmlDom; } catch(e) { xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.loadXML(xmlContent); return xmlDoc; } }, /** * 获取xml子节点 * @param{domNode}dom节点 * @param{subNodeName}子节点名称 */ getXMLSubNodes : function (domNode, subNodeName) { var subNodes = []; var currentNode = domNode; var childNodes = null; var paths = subNodeName.split ("/"); for (var i = 0; paths != null && i < paths.length-1; i++) { if (paths[i] == "") continue; childNodes = currentNode.childNodes; for (var j = 0; childNodes != null && j < childNodes.length; j++) { if (childNodes[j].nodeName.toLowerCase() == paths[i].toLowerCase()) { currentNode = childNodes[j]; break; } } } childNodes = currentNode.childNodes; for (var i = 0; i < childNodes.length; i++) { if (childNodes[i].nodeName.toLowerCase() == paths[paths.length-1].toLowerCase()) subNodes.push (childNodes[i]); } return subNodes; }, /** * 获取xml根节点 * @param{doc}xml对象 */ getXMLRootNode : function (doc) { if (doc == null) return null; return doc.documentElement; }, getXMLChildNodes: function(root) { var itemNodes = []; var nodes = root.childNodes; for(var i=0;i<nodes.length;i++) { if(nodes[i].nodeType == 1) { itemNodes.push(nodes[i]); //alert(nodes[i].nodeName + nodes[i].nodeType); } } return itemNodes; }, getXMLChildNode: function(doc_el, nodeName) { var element = doc_el.getElementsByTagName (nodeName); return element.documentElement; }, /** * 获取xml节点的值 * @param{doc}xml对象 * @param{NodeName}节点名称 */ getXMLNodeValue : function (doc,nodeName) { if (doc == null) { return null; } return XMLJS.getXMLSingleNodeValue (doc.documentElement, nodeName); }, /** * 简化 DOM 访问的函数 * @param{doc_el} req.responseXML.documentElement * @param{name} getElementsByTagName("name"), element name * @param{idx} element index,exp:elements[0].firstChild.data * @return nodevalue * */ getXMLSingleNodeValue: function(doc_el, nodeName) { var element = doc_el.getElementsByTagName (nodeName); var nodevalue = ""; if(element[0].firstChild != null) { nodevalue =element[0].firstChild.nodeValue; } return nodevalue; //return element[0].firstChild.nodeValue; }, /** * 获取xml节点的值 * @param{doc}xml对象 * @param{NodeName}节点名称 */ getAttributeNodeValues : function (doc_el,nodeName,attributeName) { if (doc_el == null) { return null; } var values = []; var len = doc_el.length; var value = ""; for(var i = 0; i < len; i++) { if(doc_el[i].nodeName == nodeName) { value = doc_el[i].getAttribute(attributeName); values.push(value); } } return values; }, /** * 获取节点属性值的方法 * @param{doc_el} req.responseXML.documentElement * @param{attributeName} node Attribute name * @return nodevalue * */ getAttributeNodeValue: function(doc_el,attributeName) { var nodevalue = ""; if(doc_el != null) { nodevalue =doc_el.getAttribute(attributeName); } return nodevalue; } }); /** * @deprecated 调用初始化xml文件对象方法,必须在定义后才能调用 * */ XMLJS.initDocs();
test.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>testXML</title>
<script type="text/javascript" src="parseXML.js"></script>
<style type="text/css">
html,body{font-size:14px;color:#333333; margin:0px;padding:0px; line-height:120%; overflow:hidden;}
</style>
<script type="text/javascript">
function subArticle()
{
//var appendixXML = "<response sessionID='48C14D02578E9D28D3E897671378E331' status='ok' />";
var appendixXML = "<response sessionID='48C14D02578E9D28D3E897671378E331' status='ok'><aa id='a1' cc='dd'></aa><aa id='a2' cc='ee'></aa><bb id='b1'></bb></response>";
//var appendixXML = "<?xml version=\"1.0\" encoding=\"gbk\"?><diagram><title><dept></dept><aname></aname><titlehtml></titlehtml><child><title><dept></dept><aname></aname><titlehtml></titlehtml><child></child></title><title><dept></dept><aname></aname><titlehtml></titlehtml><child></child></title></child></title></diagram>";
//测试,示例代码:
var doc = XMLJS.parseXML(appendixXML);
var root = XMLJS.getXMLRootNode(doc);
//根节点属性要传入root
var sessionID = XMLJS.getAttributeNodeValue(root,"sessionID");
alert(sessionID);//48C14D02578E9D28D3E897671378E331
var nodes = XMLJS.getXMLChildNodes(root);//根节点下面所有子节点元素对象
//alert(nodes);//[object Element],[object Element],[object Element]
var aa_id = XMLJS.getAttributeNodeValues(nodes,"aa","id");
//alert(aa_id);//a1,a2
var aa_cc = XMLJS.getAttributeNodeValues(nodes,"aa","cc");
//alert(aa_cc);//dd,ee
var bb_id = XMLJS.getAttributeNodeValues(nodes,"bb","id");
//alert(bb_id);//b1
// var titles = XMLJS.getXMLChildNodes(root);
// var title = titles[0];
// var dept = XMLJS.getXMLSingleNodeValue(title,"dept");
// alert(dept);
}
</script>
</head>
<body>
<center>
<div id="testxml" onClick="subArticle()" style="margin:5px;text-align:center; vertical-align:middle; font-size:18px; color:#FF0000;">testxml onclick hear!</div>
</center>
</body>
</html>
另外再分享一个实际中的应用:
获得编辑器中生成的xml,并解析成目录树形式的html输出预览
应用到xml解析的部分已经加亮显示了
viewArticle.js
var isIE = navigator.userAgent.indexOf("MSIE")>0;
function $(id)
{
return document.getElementById(id);
}
function StringBuffer()
{
var arr = new Array;
this.append = function(str)
{
arr[arr.length] = str;
};
this.toString = function()
{
return arr.join("");
};
}
//为了火狐的预览setTimeout设置全局变量
var viewhtml = "";
var editor_win = null;
function getAppendixHTMLFromXML(type,position,left,top,width,height,position)
{
if(left == null)
left = 720;
if(top == null)
top = 30;
if(width == null)
width = 220;
if(height == null)
height = 400;
if(position == null)
position = "absolute";
var container = "";
if(type.toLowerCase() == "nodiv")
{
container = "<fieldset><legend style='font-weight:bold;font-size:14px;'>目录</legend>";
}
else
{
container = "<div style='margin:0px;padding:0px;position:" + position + ";left:" + parseInt(left) + "px;top:" + parseInt(top) + "px;width:" + parseInt(width) + "px;height:" + parseInt(height) + "px;'><fieldset><legend style='font-weight:bold;font-size:14px;'>目录</legend>";
}
var appendixXML = $("Editor").contentWindow.getAppendixXML();
var doc = XMLJS.parseXML(appendixXML);
var root = XMLJS.getXMLRootNode(doc);
var titles = XMLJS.getXMLChildNodes(root);
var sb = new StringBuffer();
sb.append(container);
var titlediv = parseXMLTree(titles);
sb.append(titlediv);
if(type.toLowerCase() == "nodiv")
{
sb.append ("</fieldset>");
}
else
{
sb.append ("</fieldset></div>");
}
return sb.toString();
}
//文章预览
function article_preview()
{
var EditorHTML = $("Editor").contentWindow.getHTML();
//var appendixXML = $("Editor").contentWindow.getAppendixXML();
//var xmltree = creatXMLTree(appendixXML);
//var xmltree = getAppendixHTMLFromXML();
var xmltree = $("Editor").contentWindow.getAppendixHTML(null,null,null,null,null,null);
var viewhtml = EditorHTML + xmltree;
openPreviewWin(viewhtml)
}
function openPreviewWin(viewhtml)
{
if(isIE)
{
var starthtml = "<html>"
+ "<head>"
+ "<title>article preview</title>"
+ "<style>"
+ "html,body{font-size:12px;padding-top:3px;padding-left:3px;padding-right:0px;margin:0px}"
+ "p{margin:0;padding:0;}"
+ "</style>"
+ "</head>"
+ "<body>";
var endhtml = "</body></html>";
viewhtml = starthtml + viewhtml + endhtml;
editor_win = window.open('', "_blank", '');
editor_win.document.open('text/html', 'replace');
editor_win.opener = null ;
editor_win.document.writeln(viewhtml);
editor_win.document.close();
}
else
{
if(editor_win == null)
{
editor_win = window.open('view.html', "_blank", '');
}
if(editor_win.document.body.innerHTML)
{
editor_win.document.body.innerHTML = viewhtml;
}
else
{
setTimeout(openPreviewWin,100);
}
}
}
function creatXMLTree(appendixXML)
{
var doc = XMLJS.parseXML(appendixXML);
var root = XMLJS.getXMLRootNode(doc);
var titles = XMLJS.getXMLChildNodes(root);
var sb = new StringBuffer();
var container = "<div id='title' style='position:absolute;left:720px;top:30px;width:220px;height:400px;padding:2px;margin:2px;border: 1px solid #cccccc;'>";
sb.append(container);
var titlediv = parseXMLTree(titles);
sb.append(titlediv);
sb.append("</div>");
return sb.toString();
}
function parseXMLTree(titles)
{
if(!titles)
{
return;
}
var sb = new StringBuffer();
var xmlnode = "";
for(var i = 0; i < titles.length; i++)
{
var title = titles[i];
var dept = XMLJS.getXMLSingleNodeValue(title,"dept");
var aname = XMLJS.getXMLSingleNodeValue(title,"aname");
var titlehtml = XMLJS.getXMLSingleNodeValue(title,"titlehtml");
var margin = "";
for(var j = 1; j < dept; j++)
{
margin += " ";
}
xmlnode = "<div>" + margin + "<a href='#" + aname + "' style='text-decoration:none;'>" + titlehtml + "</a></div>";
sb.append(xmlnode);
var child = title.lastChild;
if(child.hasChildNodes())//递归调用
{
var childs = XMLJS.getXMLChildNodes(child);
xmlnode = parseXMLTree(childs);
sb.append(xmlnode);
}
}
return sb.toString();
}
原文地址:http://hi.baidu.com/zdz8207/blog/item/934e8eb14ec51d520823020a.html