Skip to content

Commit

Permalink
更换 xml 和 json 转换的库
Browse files Browse the repository at this point in the history
  • Loading branch information
carsonxu committed Oct 31, 2017
1 parent 60a871b commit 48a755e
Show file tree
Hide file tree
Showing 3 changed files with 374 additions and 25 deletions.
166 changes: 166 additions & 0 deletions lib/json2xml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//copyright Ryan Day 2010 <http://ryanday.org>, Joscha Feth 2013 <http://www.feth.com> [MIT Licensed]

var element_start_char =
"a-zA-Z_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FFF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
var element_non_start_char = "\-.0-9\u00B7\u0300-\u036F\u203F\u2040";
var element_replace = new RegExp("^([^" + element_start_char + "])|^((x|X)(m|M)(l|L))|([^" + element_start_char + element_non_start_char + "])", "g");
var not_safe_in_xml = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm;

var objKeys = function (obj) {
var l = [];
if (obj instanceof Object) {
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
l.push(k);
}
}
}
return l;
};
var process_to_xml = function (node_data, options) {

var makeNode = function (name, content, attributes, level, hasSubNodes) {
var indent_value = options.indent !== undefined ? options.indent : "\t";
var indent = options.prettyPrint ? '\n' + new Array(level).join(indent_value) : '';
if (options.removeIllegalNameCharacters) {
name = name.replace(element_replace, '_');
}

var node = [indent, '<', name, (attributes || '')];
if (content && content.length > 0) {
node.push('>')
node.push(content);
hasSubNodes && node.push(indent);
node.push('</');
node.push(name);
node.push('>');
} else {
node.push('/>');
}
return node.join('');
};

return (function fn(node_data, node_descriptor, level) {
var type = typeof node_data;
if ((Array.isArray) ? Array.isArray(node_data) : node_data instanceof Array) {
type = 'array';
} else if (node_data instanceof Date) {
type = 'date';
}

switch (type) {
//if value is an array create child nodes from values
case 'array':
var ret = [];
node_data.map(function (v) {
ret.push(fn(v, 1, level + 1));
//entries that are values of an array are the only ones that can be special node descriptors
});
options.prettyPrint && ret.push('\n');
return ret.join('');
break;

case 'date':
// cast dates to ISO 8601 date (soap likes it)
return node_data.toJSON ? node_data.toJSON() : node_data + '';
break;

case 'object':
var nodes = [];
for (var name in node_data) {
if (node_data[name] instanceof Array) {
for (var j in node_data[name]) {
nodes.push(makeNode(name, fn(node_data[name][j], 0, level + 1), null, level + 1, objKeys(node_data[name][j]).length));
}
} else {
nodes.push(makeNode(name, fn(node_data[name], 0, level + 1), null, level + 1));
}
}
options.prettyPrint && nodes.length > 0 && nodes.push('\n');
return nodes.join('');
break;

case 'function':
return node_data();
break;

default:
return options.escape ? esc(node_data) : '' + node_data;
}

}(node_data, 0, 0))
};


var xml_header = function (standalone) {
var ret = ['<?xml version="1.0" encoding="UTF-8"'];

if (standalone) {
ret.push(' standalone="yes"');
}
ret.push('?>');

return ret.join('');
};

function esc(str) {
return ('' + str).replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&apos;')
.replace(/"/g, '&quot;')
.replace(not_safe_in_xml, '');
}

module.exports = function (obj, options) {

if (!options) {
options = {
xmlHeader: {
standalone: true
},
prettyPrint: true,
indent: " "
};
}

var Buffer = this.Buffer || function Buffer() {
};

if (typeof obj == 'string' || obj instanceof Buffer) {
try {
obj = JSON.parse(obj.toString());
} catch (e) {
return false;
}
}

var xmlheader = '';
var docType = '';
if (options) {
if (typeof options == 'object') {
// our config is an object

if (options.xmlHeader) {
// the user wants an xml header
xmlheader = xml_header(!!options.xmlHeader.standalone);
}

if (typeof options.docType != 'undefined') {
docType = '<!DOCTYPE ' + options.docType + '>'
}
} else {
// our config is a boolean value, so just add xml header
xmlheader = xml_header();
}
}
options = options || {}

var ret = [
xmlheader,
(options.prettyPrint && docType ? '\n' : ''),
docType,
process_to_xml(obj, options)
];
return ret.join('').replace(/\n{2,}/g, '\n').replace(/\s+$/g, '');
};
164 changes: 164 additions & 0 deletions lib/xml2json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/* Copyright 2015 William Summers, MetaTribal LLC
* adapted from https://developer.mozilla.org/en-US/docs/JXON
*
* Licensed under the MIT License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author William Summers
* https://github.com/metatribal/xmlToJSON
*/

var xmlToJSON = (function () {

this.version = "1.3.5";

var options = { // set up the default options
mergeCDATA: true, // extract cdata and merge with text
normalize: true, // collapse multiple spaces to single space
stripElemPrefix: true, // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
};

var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
var trimMatch = new RegExp(/^\s+|\s+$/g);

this.grokType = function (sValue) {
if (/^\s*$/.test(sValue)) {
return null;
}
if (/^(?:true|false)$/i.test(sValue)) {
return sValue.toLowerCase() === "true";
}
if (isFinite(sValue)) {
return parseFloat(sValue);
}
return sValue;
};

this.parseString = function (xmlString, opt) {
if (xmlString) {
var xml = this.stringToXML(xmlString);
if (xml.getElementsByTagName('parsererror').length) {
return null;
} else {
return this.parseXML(xml, opt);
}
} else {
return null;
}
};

this.parseXML = function (oXMLParent, opt) {

// initialize options
for (var key in opt) {
options[key] = opt[key];
}

var vResult = {},
nLength = 0,
sCollectedTxt = "";

// iterate over the children
var childNum = oXMLParent.childNodes.length;
if (childNum) {
for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
oNode = oXMLParent.childNodes.item(nItem);

if (oNode.nodeType === 4) {
if (options.mergeCDATA) {
sCollectedTxt += oNode.nodeValue;
}
} /* nodeType is "CDATASection" (4) */
else if (oNode.nodeType === 3) {
sCollectedTxt += oNode.nodeValue;
} /* nodeType is "Text" (3) */
else if (oNode.nodeType === 1) { /* nodeType is "Element" (1) */

if (nLength === 0) {
vResult = {};
}

// using nodeName to support browser (IE) implementation with no 'localName' property
if (options.stripElemPrefix) {
sProp = oNode.nodeName.replace(prefixMatch, '');
} else {
sProp = oNode.nodeName;
}

vContent = xmlToJSON.parseXML(oNode);

if (vResult.hasOwnProperty(sProp)) {
if (vResult[sProp].constructor !== Array) {
vResult[sProp] = [vResult[sProp]];
}
vResult[sProp].push(vContent);

} else {
vResult[sProp] = vContent;
nLength++;
}
}
}
}

if (!Object.keys(vResult).length) {
vResult = sCollectedTxt.replace(trimMatch, '') || '';
}

return vResult;
};

// Convert xmlDocument to a string
// Returns null on failure
this.xmlToString = function (xmlDoc) {
try {
var xmlString = xmlDoc.xml ? xmlDoc.xml : (new XMLSerializer()).serializeToString(xmlDoc);
return xmlString;
} catch (err) {
return null;
}
};

// Convert a string to XML Node Structure
// Returns null on failure
this.stringToXML = function (xmlString) {
try {
var xmlDoc = null;

if (window.DOMParser) {

var parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlString, "text/xml");

return xmlDoc;
} else {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(xmlString);

return xmlDoc;
}
} catch (e) {
return null;
}
};

return this;

}).call({});

var xml2json = function (xmlString) {
return xmlToJSON.parseString(xmlString);
};

module.exports = xml2json;
Loading

0 comments on commit 48a755e

Please sign in to comment.