Skip to content
Browse files

提交优化版本

在原著基础上进行了优化,解决了以下问题:
1、节点中存在CDATA被过滤的问题;
2、空值被处理为对象、其余数据均为字符串的问题;
3、增加代码注释,增加代码注释,方便日后各位优化;
4、节点的多属性支持。
5、去掉了内置的DEBUG和不做节点解析的部分(对我用处不大,所以被优化掉了)。
  • Loading branch information...
1 parent 2ffb73a commit f07be5597142ddeb69fa9e1fde2cb5a3b4588535 @yhostc committed Sep 1, 2012
Showing with 138 additions and 0 deletions.
  1. +1 −0 index.js
  2. +130 −0 lib/xml2json.js
  3. +7 −0 test/demo.js
View
1 index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/xml2json');
View
130 lib/xml2json.js
@@ -0,0 +1,130 @@
+/*
+* XML2JSON package for Node.js
+* Author : Thomas Frank(2005-2007)
+* Update : yhostc@gmail.com
+* version : 1.0
+* Date : 2012-09-01
+* Project : https://github.com/yhostc/XML2JSON
+*
+* 使用:
+* var xml2json = require("XML2JSON");
+* var xml = "<poi><pguid>B000A2E9FB</pguid><name><![CDATA[中关村广场]]></name><code>110108</code>"
+* var json = xml2json.parser( xml );
+* myJsonObject=xml2json.parser(str);
+* console.log( json );
+*/
+
+module.exports = {
+ parser : function(/*带解析的XML字符串*/xml){
+ // 转换不做解析的节点名称数组
+ var tags = tags || '';
+ tags = tags instanceof Array ? tags : tags.split(',');
+ // 替换掉右边界符前N个空格
+ xml = xml.replace(/\s*\/>/g,'/>');
+ // 替换掉左节点有边界钱N个空格
+ xml = xml.replace(/\s*>/g,'>');
+ // CDATA片区替换
+ xml = xml.replace(/<!\[CDATA\[(.*?)\]\]>/g, "$1");
+ // 去除所有问号包含部分
+ xml = xml.replace(/<\?[^>]*>/g,"").replace(/<\![^>]*>/g, "");
+ // 将快速结束符解析为普通节点
+ var x = this.fastending2normal(xml);
+ // 转换子属性为子节点
+ x = this.attris2tags(x);
+ return this.xml_to_object(x);
+ },
+ // 将XML解析为JSON
+ xml_to_object : function(xml){
+ // 将右节点右边界符替换掉
+ var x = xml.replace(/<\//g,"");
+ // 以左节点左边界符分割为数组,即:节点组数组
+ x = x.split("<");
+ var json = {};
+ var tags = ['json'];
+ /**/
+ // 循环每个节点组
+ for (var i=1; i < x.length; i++){
+ // 节点行
+ var row = x[i].split("");
+ // 分析节点名称及值
+ var key_value = row[0].split('>'), tagname = key_value[0], val = key_value[1];
+ // 检测右节点是否在此行出现,如存在右节点,则为数据行,否则为下级做好存储对象
+ if(!row[1]){//节点行 "searchresult>"
+ tags.push(tagname);
+ var origin = eval(tags.join('.'));
+ if(!origin){//节点不存在,则创建对象
+ eval(tags.join('.')+'={}');
+ }else if(!(origin instanceof Array)){// 节点存在,调整为数组
+ var topNode = tags.join('.');
+ eval(topNode+'=[]');
+ eval(topNode+'.push(origin,{})');
+ }else{
+ eval(tags.join('.')+'.push({})');
+ }
+ }else{//数据行 "time>23"
+ val = !val ? "" : val ;
+ val = val && !isNaN(val) ? Number(val) : val;
+ var obj = eval(tags.join('.'));
+ if(obj instanceof Array){
+ obj[obj.length-1][tagname] = val;
+ }else{
+ eval(tags.join('.')+'.'+tagname+'=val');
+ }
+ }
+ if(row.length>2){//如果检测到额外的结束节点,则退上一级
+ for(var j=2; j<row.length; j++){
+ tags.pop();
+ }
+ }
+ };
+ return json;
+ },
+ // 解析快速结束符号为普通节点 <pinyin/> -> <pinyin></pinyin>
+ fastending2normal:function(x){
+ x = x.split("/>");
+ for (var i=1; i < x.length; i++){
+ var t = x[i-1].substring(x[i-1].lastIndexOf("<")+1).split(" ")[0];
+ x[i] = "></"+t+">" + x[i];
+ }
+ x = x.join("");
+ return x;
+ },
+ // 属性变子节点 <a type="list"><a> -> <a><type>list</type></a>
+ attris2tags: function(x){
+ //进行内容预处理,做字符的保护处理
+ var d = ' ="\''.split('');
+ x = x.split(">");//对节点进行分析
+ for (var i=0; i<x.length; i++){
+ var temp = x[i].split("<");
+ for (var r=0; r<4; r++){//节点左侧部分
+ temp[0] = temp[0].replace(new RegExp(d[r],"g"),"_jsonconvtemp"+r+"_");//将所有符号进行转义
+ }
+ if(temp[1]){//节点右侧部分
+ temp[1] = temp[1].replace(/'/g,'"');//单引号转为双引号
+ temp[1] = temp[1].split('"');
+ for (var j=1; j<temp[1].length; j+=2){
+ for (var r=0; r<4; r++){
+ temp[1][j] = temp[1][j].replace(new RegExp(d[r],"g"), "_jsonconvtemp"+r+"_")
+ }
+ };
+ temp[1] = temp[1].join('"')
+ };
+ x[i] = temp.join("<")
+ };
+ x = x.join(">");
+ // 将所有属性等号前后空格替换掉
+ x = x.replace(/(\s*)=(\s*)/g, "=");
+ // 将属性变为子节点
+ x = x.replace(/ ([^=]*)=([^ |>]*)/g, "><$1>$2</$1");
+ // 替换掉值中的引号
+ x = x.replace(/>"/g,">").replace(/"</g,"<");
+ // 清楚右边界前空格
+ x = x.replace(/\w\s+>/g,'>');
+ // 还原被保护字符
+ for (var r=0; r<4; r++){
+ x = x.replace(new RegExp("_jsonconvtemp"+r+"_","g"), d[r]);
+ }
+
+ return x;
+ }
+};
View
7 test/demo.js
@@ -0,0 +1,7 @@
+var xml = "<?xml version='1.0' encoding='GBK'?><searchresult><count>1</count><searchtime>0</searchtime><pinyin><list type=\"list\"></list></pinyin><list type=\"list\"><poi><pguid>B000A2E9FB</pguid><name><![CDATA[中关村广场]]></name><code>110108</code><typecode>110105</typecode><oritype><![CDATA[风景名胜;公园广场;城市广场]]></oritype><newtype>110105</newtype><type><![CDATA[风景名胜;公园广场;城市广场]]></type><group></group><container></container><address><![CDATA[]]></address><tel></tel><gridcode>5916727510</gridcode><x>116.316366</x><y>39.979495</y><match>10</match><buscode></buscode><querylevel></querylevel><imageid>0a802008042600000945</imageid><url></url><keywords><![CDATA[]]></keywords><introduction><![CDATA[]]></introduction><xml></xml><cpid>B0</cpid><linkid></linkid><version><![CDATA[11Q3]]></version><timestamp>2011-08-31</timestamp><citycode>010</citycode><srctype>basepoi</srctype><distance>0</distance></poi></list></searchresult>";
+
+xml2 = "<xml><category><id>1</id><name>Programmer</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=1</url><intro></intro><order>1</order><count>3</count></category><category><id>5</id><name>Others</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=5</url><intro></intro><order>5</order><count>62</count></category><category><id>6</id><name>Diarys</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=6</url><intro></intro><order>4</order><count>32</count></category><category><id>7</id><name>Messag</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=7</url><intro></intro><order>0</order><count>11</count></category><category><id>8</id><name>Product</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=8</url><intro></intro><order>3</order><count>7</count></category><category><id>9</id><name>Web Design</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=9</url><intro></intro><order>2</order><count>1</count></category><category><id>10</id><name>Product-Flex</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=10</url><intro></intro><order>6</order><count>129</count></category><category><id>11</id><name>Apollo</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=11</url><intro></intro><order>7</order><count>8</count></category><category><id>12</id><name>ZBLOG修改</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=12</url><intro></intro><order>8</order><count>20</count></category><category><id>14</id><name>培训与招聘</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=14</url><intro></intro><order>9</order><count>21</count></category><category><id>15</id><name>产品介绍</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=15</url><intro></intro><order>10</order><count>9</count></category><category><id>16</id><name>闲言碎语</name><url>http://www.k-zone.cn/zblog/catalog.asp?cate=16</url><intro></intro><order>11</order><count>4</count></category></xml>";/**/
+console.log(xml2json.parser(xml));
+
+console.log(xml2json.parser(xml2));
+

0 comments on commit f07be55

Please sign in to comment.
Something went wrong with that request. Please try again.