UNPKG

weixinpay-sdk

Version:

基于微信官方的原生 API 封装而成的 SDK,将官方要求的 xml 格式均通过 sdk 转换成 JSON 格式方便开发,当前已支持 Native

141 lines (138 loc) 4.91 kB
/* * 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 ); */ /** * 修改说明,本人再使用该 xml 转换时发现了一个问题 * 微信的订单号是 32 位纯数字字符串,但是经过该模块 * 转换后所有的纯数字字符串均会变成 Number 在 JS 中 * 当 Number 超过 16 位时会丢失精度,并且特大数会自 * 动转换为科学技术方式所以在此单独拿出来修改一下,当 * 长度超过 15 位时就转换为字符串,反之为数字 * */ 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) ? (String(val).length<=15?Number(val):String(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; } };