-
Notifications
You must be signed in to change notification settings - Fork 566
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
374 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, '&') | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/'/g, ''') | ||
.replace(/"/g, '"') | ||
.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, ''); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.