一个快捷操作XML数据库的Javascript接口对象,包含select、count、tables、fields等方法,能够像操作mysql等其它数据库一样操作XML数据库。
1 if(document.implementation.hasFeature("XPath","3.0")){ //浏览器bug修复 2 XMLDocument.prototype.selectNodes=function(cXPathString,xNode){ 3 if(!xNode){xNode=this;} 4 var oNSResolver=this.createNSResolver(this.documentElement); 5 var aItems=this.evaluate(cXPathString, xNode, oNSResolver,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 6 var aResult=[]; 7 for(var i=0;i< aItems.snapshotLength;i++){ 8 aResult[i]=aItems.snapshotItem(i); 9 } 10 return aResult; 11 } 12 Element.prototype.selectNodes=function(cXPathString){ 13 if(this.ownerDocument.selectNodes){ 14 return this.ownerDocument.selectNodes(cXPathString,this); 15 }else{throw "For XML Elements Only";} 16 } 17 } 18 /* 19 jQuery版本要求:1.7.2 20 XML数据库查询类,实现的方法 21 load(pt,async): 22 loadFromText(xStr): 23 select(tb,data,where,order,limit,group); 24 count(tb,where); 25 tables(); 26 fields(tb); 27 */ 28 function xml_db(pt,async){ 29 var _root=this,async=typeof(async)!="undefined"?async:true; 30 _root.dbObj=null;/*数据库对象数组*/ 31 _root.status=false;/*数据库对象数组*/ 32 _root.dbpath=typeof(pt)!="undefined"?pt:false;/*数据库路径*/ 33 _root.ifAutoPara=true; 34 35 var autoPara=function(para,oriParas){/*自动附加参数*/ 36 if(para.length >2){ 37 for(var i=2;i< para.length;i++){ 38 if(para[i].match(/^s*where/i)){oriParas['where']=para[i];} 39 if(para[i].match(/^s*order/i)){oriParas['order']=para[i];} 40 if(para[i].match(/^s*limit/i)){oriParas['limit']=para[i];} 41 if(para[i].match(/^s*group/i)){oriParas['group']=para[i];} 42 } 43 } 44 }, 45 WOLG=function(str,kw,oriParas){/*附加参数*/ 46 if(typeof(str)!="undefined"){ 47 var reg=new RegExp("^"+kw+"\s*","ig"),ky=kw.replace(/s+w+/gi,""); 48 str=str.replace(reg,""); 49 oriParas[ky]=kw+" "+str; 50 } 51 }, 52 decode=function(string,quote_style){/*解码*/ 53 var optTemp=0,i=0,noquotes=false; 54 if(typeof quote_style === 'undefined'){quote_style=2;} 55 string=string.toString().replace(/</g, '<').replace(/>/g, '>'); 56 var OPTS={'ENT_NOQUOTES': 0,'ENT_HTML_QUOTE_SINGLE': 1,'ENT_HTML_QUOTE_DOUBLE':2,'ENT_COMPAT':2,'ENT_QUOTES':3,'ENT_IGNORE':4}; 57 if(quote_style===0){noquotes=true;} 58 if(typeof quote_style !== 'number'){ 59 quote_style=[].concat(quote_style); 60 for(i=0; i < quote_style.length; i++){ 61 if(OPTS[quote_style[i]] === 0){ 62 noquotes=true; 63 }else if(OPTS[quote_style[i]]){ 64 optTemp=optTemp | OPTS[quote_style[i]]; 65 } 66 } 67 quote_style=optTemp; 68 } 69 if(quote_style & OPTS.ENT_HTML_QUOTE_SINGLE){ 70 string=string.replace(/�*39;/g, "'"); 71 string=string.replace(/'|�*27;/g, "'"); 72 } 73 if(!noquotes){string=string.replace(/"/g, '"');} 74 string=string.replace(/&/g, '&'); 75 return string; 76 }, 77 xQuery=function(str,node){ 78 return typeof(node)!="undefined"? node.selectNodes(str):_root.dbObj.selectNodes(str); 79 }; 80 81 _root.load=function(pt,async){ 82 var pt=typeof(pt)!="undefined"?pt:_root.dbpath, 83 async=typeof(async)!="undefined"?async:true; 84 jQuery.ajax({ 85 'type': "GET", 86 'url':pt, 87 'dataType':'text', 88 'cache': false, 89 'async': async, 90 'success': function(dt){ 91 var root=_root.loadFromText(dt.replace(/[ ]+/gmi,"").replace(/<!--.*?-->/gi,"").replace(/>s+/gi,">")); 92 if(root){ 93 _root.dbObj=root.documentElement; 94 } 95 } 96 }); 97 }; 98 99 _root.loadFromText=function (xStr){ 100 try{ 101 if(window.DOMParser){ 102 parser=new DOMParser(); 103 txmlDoc=parser.parseFromString(xStr,"text/xml"); 104 }else{ 105 txmlDoc=new ActiveXObject("Microsoft.XMLDOM"); 106 txmlDoc.async="false"; 107 txmlDoc.loadXML(xStr); 108 } 109 _root.status=txmlDoc.documentElement?true:false; 110 return _root.status?txmlDoc:false; 111 }catch(e){ 112 _root.status=false; 113 return false; 114 } 115 }; 116 117 _root.query=function(){ 118 119 }; 120 121 _root.select=function(tb,data,where,order,limit,group){ 122 if(!_root.status){return false;} 123 var addtion={},data=typeof(data)=="undefined"?"*":data; 124 if(!_root.ifAutoPara){ /*自动附加参数*/ 125 autoPara(arguments,addtion); 126 }else{ 127 WOLG(where,"where",addtion); 128 WOLG(order,"order by",addtion); 129 WOLG(limit,"limit",addtion); 130 WOLG(group,"group by",addtion); 131 } 132 133 if(typeof(addtion['where'])=="undefined"){ 134 addtion['where']="where `id`>=0"; 135 } 136 addtion['where']=addtion['where'].replace(/&&/gi," and ").replace(/||/gi," or "); 137 addtion['where']=addtion['where'].replace(/^s*wheres*/gi,""); 138 139 var fdArr=_root.fields(tb),sFdArr,reg=new RegExp(),oArr,rArr=[];/*相关变量定义*/ 140 141 if(data!="*"){ 142 sFdArr=jQuery.grep( 143 jQuery.type(data)=="array"?data:data.split(/s*,s*/gi),function(n,i){ 144 return jQuery.inArray(n,fdArr)!=-1; 145 }); 146 if(!sFdArr.length){return false;} 147 if(jQuery.inArray("id",sFdArr)==-1){sFdArr.push("id");} 148 } 149 jQuery.each(fdArr,function(i,n){ 150 reg.compile('`'+n+'`',"gi"); 151 addtion['where']=addtion['where'].replace(reg,"v"+i); 152 }); 153 oArr=xQuery("//root/"+tb+"/it["+addtion['where']+"]"); 154 jQuery.each(oArr,function(i,n){ 155 var orArr={}; 156 jQuery.each(n.childNodes,function(dx,cNode){ 157 var curVL=jQuery(cNode).text(); 158 curVL=curVL.match(/^d+$/,"gi")?parseInt(curVL):(curVL.match(/^d+.d+$/,"gi")?parseFloat(curVL):decode(curVL)); 159 if(data=="*"){ 160 orArr[fdArr[dx]]=curVL; 161 }else if(jQuery.inArray(fdArr[dx],sFdArr)!=-1){ 162 orArr[fdArr[dx]]=curVL; 163 } 164 }); 165 rArr.push(orArr); 166 }); 167 168 if(typeof(addtion['order'])!="undefined"){ 169 if(addtion['order'].match(/^s*orders+bys+`?(w+)`?s+(asc|desc)s*$/gi)){ 170 var orders=[]; 171 orders[0]=(jQuery.inArray(RegExp.$1.toString(),fdArr)!=-1)?RegExp.$1.toString():"id"; 172 orders[1]=(jQuery.inArray(RegExp.$2.toString(),["desc","asc"])!=-1)?RegExp.$2.toString():"desc"; 173 rArr.sort(function(a,b){ 174 var ca=0,cb=0; 175 if(a[orders[0]].toString().match(/^d+$/gi)&&b[orders[0]].toString().match(/^d+$/gi)){ 176 ca=parseInt(a[orders[0]]);cb=parseInt(b[orders[0]]); 177 }else if(a[orders[0]].toString().match(/^d+.d+$/gi)&&b[orders[0]].toString().match(/^d+.d+$/gi)){ 178 ca=parseFloat(a[orders[0]]);cb=parseFloat(b[orders[0]]); 179 }else{ 180 ca=a[orders[0]];cb=b[orders[0]]; 181 } 182 if(ca==cb)return 0; 183 if(orders[1].toLowerCase()=='asc'){ 184 return (ca > cb)? 1 : -1; 185 }else{ 186 return (ca < cb)? 1 : -1; 187 } 188 }); 189 } 190 }; 191 if(typeof(addtion['limit'])!="undefined"){ 192 if(addtion['limit'].match(/^s*limits+(d+)s*,s*(d+)s*$/gi)){ 193 var itemsnum=rArr.length,snum=parseInt(RegExp.$1),lenum=parseInt(RegExp.$2); 194 snum=(snum < 0) ? 0:(snum < itemsnum ? snum : (itemsnum-1)); 195 rArr2=[]; 196 for(var i=0;i< itemsnum;i++){ 197 if(i >= snum && i <= (snum+lenum-1)){ 198 rArr2.push(rArr[i]); 199 } 200 } 201 return rArr2; 202 } 203 } 204 return rArr; 205 }; 206 207 _root.count=function(tb,where){ 208 if(!_root.status){return false;} 209 var fdArr=_root.fields(tb),reg=new RegExp(),addtion={}; 210 WOLG(where,"where",addtion); 211 if(typeof(addtion['where'])=="undefined"){ 212 addtion['where']="where `id`>=0"; 213 } 214 addtion['where']=addtion['where'].replace(/&&/gi," and ").replace(/||/gi," or "); 215 addtion['where']=addtion['where'].replace(/^s*wheres*/gi,""); 216 jQuery.each(fdArr,function(i,n){ 217 reg.compile('`'+n+'`',"gi"); 218 addtion['where']=addtion['where'].replace(reg,"v"+i); 219 }); 220 return xQuery("//root/"+tb+"/it["+addtion['where']+"]").length; 221 }; 222 223 _root.fields=function(tb){ 224 if(!_root.status){return false;} 225 var tbInfo=xQuery('//root/'+tb); 226 return tbInfo.length >0 ? tbInfo[0].getAttribute("fd").split("|"):[]; 227 }; 228 229 _root.tables=function(){ 230 if(!_root.status){return false;} 231 var tbArr=[]; 232 jQuery.each(xQuery('//root')[0].childNodes,function(dx,n){ 233 tbArr.push(n.tagName); 234 }); 235 return tbArr; 236 } 237 238 if(_root.dbpath!==false){ 239 _root.load(_root.dbpath,async); 240 } 241 242 }
XML数据库文件格式(文件名为:db.xml):
<?xml version="1.0" encoding="UTF-8"?> <root> <menu fd="id|name|mtype|level|year|major"> <it> <v0>1</v0> <v1>云南财经大学</v1> <v2></v2> <v3>专升本</v3> <v4>3年</v4> <v5>工商管理</v5> </it> <it> <v0>2</v0> <v1>云南财经大学</v1> <v2></v2> <v3>专升本</v3> <v4>3年</v4> <v5>会计学</v5> </it> <it> <v0>3</v0> <v1>云南财经大学</v1> <v2></v2> <v3>专升本</v3> <v4>3年</v4> <v5>金融学</v5> </it> <it> <v0>4</v0> <v1>云南财经大学</v1> <v2></v2> <v3>高升专</v3> <v4>3年</v4> <v5>法律事务</v5> </it> </menu> </root>
使用方法介绍:
var dbObj=new xml_db("db.xml",false); var data=dbObj.select("menu","id,name,major","where `major`!='金融学'","limit 0,2","order by `id` desc"); for(var i=0;i< data.length;i++){ document.write(i+"->id:"+data[i]['id']+" name:"+data[i]['name']+" major:"+data[i]['major']+"<br/>"); }
输出:
0->id:1 name:云南财经大学 major:工商管理
1->id:2 name:云南财经大学 major:会计学
其它方法说明:
tables():返回所有表的数组;
fields(tb):返回表名为tb的所有字段名;
count(tb,where):返回表tb中符合where条件的记录数量