Added editor
This commit is contained in:
+73
@@ -0,0 +1,73 @@
|
||||
/*jslint node:true */
|
||||
|
||||
module.exports = {
|
||||
sanitize: function (text) {
|
||||
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
},
|
||||
copyOptions: function (options) {
|
||||
var key, copy = {};
|
||||
for (key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
copy[key] = options[key];
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
},
|
||||
ensureFlagExists: function (item, options) {
|
||||
if (!(item in options) || typeof options[item] !== 'boolean') {
|
||||
options[item] = false;
|
||||
}
|
||||
},
|
||||
ensureSpacesExists: function (options) {
|
||||
if (!('spaces' in options) || (typeof options.spaces !== 'number' && typeof options.spaces !== 'string')) {
|
||||
options.spaces = 0;
|
||||
}
|
||||
},
|
||||
ensureKeyExists: function (key, options) {
|
||||
if (!(key + 'Key' in options) || typeof options[key + 'Key'] !== 'string') {
|
||||
options[key + 'Key'] = options.compact ? '_' + key : key;
|
||||
}
|
||||
},
|
||||
getCommandLineHelp: function (command, requiredArgs, optionalArgs) {
|
||||
var reqArgs = requiredArgs.reduce(function (res, arg) {return res + ' <' + arg.arg + '>';}, '');
|
||||
var output = 'Usage: ' + command + reqArgs + ' [options]' + '\n';
|
||||
requiredArgs.forEach(function (argument) {
|
||||
output += ' <' + argument.arg + '>' + Array(20 - argument.arg.length).join(' ') + argument.desc + '\n';
|
||||
});
|
||||
output += '\nOptions:' + '\n';
|
||||
optionalArgs.forEach(function (argument) {
|
||||
output += ' --' + argument.arg + Array(20 - argument.arg.length).join(' ') + argument.desc + '\n';
|
||||
});
|
||||
return output;
|
||||
},
|
||||
mapCommandLineArgs: function (requiredArgs, optionalArgs) {
|
||||
var options = {}, r, o, a = 2;
|
||||
for (r = 0; r < requiredArgs.length; r += 1) {
|
||||
if (a < process.argv.length && process.argv[a].substr(0, 1) !== '-' && process.argv[a] !== 'JASMINE_CONFIG_PATH=./jasmine.json') {
|
||||
options[requiredArgs[r].option] = process.argv[a++];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; a < process.argv.length; a += 1) {
|
||||
for (o = 0; o < optionalArgs.length; o += 1) {
|
||||
if (optionalArgs[o].alias === process.argv[a].slice(1) || optionalArgs[o].arg === process.argv[a].slice(2)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (o < optionalArgs.length) {
|
||||
switch (optionalArgs[o].type) {
|
||||
case 'file': case 'string': case 'number':
|
||||
if (a + 1 < process.argv.length) {
|
||||
a += 1;
|
||||
options[optionalArgs[o].option] = (optionalArgs[o].type === 'number' ? Number(process.argv[a]) : process.argv[a]);
|
||||
}
|
||||
break;
|
||||
case 'flag':
|
||||
options[optionalArgs[o].option] = true; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
};
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*jslint node:true */
|
||||
|
||||
var xml2js = require('./xml2js');
|
||||
var xml2json = require('./xml2json');
|
||||
var js2xml = require('./js2xml');
|
||||
var json2xml = require('./json2xml');
|
||||
|
||||
module.exports = {
|
||||
xml2js: xml2js,
|
||||
xml2json: xml2json,
|
||||
js2xml: js2xml,
|
||||
json2xml: json2xml
|
||||
};
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/*jslint node:true */
|
||||
|
||||
var common = require('./common');
|
||||
|
||||
function validateOptions (userOptions) {
|
||||
var options = common.copyOptions(userOptions);
|
||||
common.ensureFlagExists('ignoreDeclaration', options);
|
||||
common.ensureFlagExists('ignoreAttributes', options);
|
||||
common.ensureFlagExists('ignoreText', options);
|
||||
common.ensureFlagExists('ignoreComment', options);
|
||||
common.ensureFlagExists('ignoreCdata', options);
|
||||
common.ensureFlagExists('compact', options);
|
||||
common.ensureFlagExists('fullTagEmptyElement', options);
|
||||
common.ensureSpacesExists(options);
|
||||
if (typeof options.spaces === 'number') {
|
||||
options.spaces = Array(options.spaces + 1).join(' ');
|
||||
}
|
||||
common.ensureKeyExists('declaration', options);
|
||||
common.ensureKeyExists('attributes', options);
|
||||
common.ensureKeyExists('text', options);
|
||||
common.ensureKeyExists('comment', options);
|
||||
common.ensureKeyExists('cdata', options);
|
||||
common.ensureKeyExists('type', options);
|
||||
common.ensureKeyExists('name', options);
|
||||
common.ensureKeyExists('elements', options);
|
||||
return options;
|
||||
}
|
||||
|
||||
function writeIndentation (options, depth, firstLine) {
|
||||
return (!firstLine && options.spaces ? '\n' : '') + Array(depth + 1).join(options.spaces);
|
||||
}
|
||||
|
||||
function writeAttributes (attributes) {
|
||||
var key, result = '';
|
||||
for (key in attributes) {
|
||||
if (attributes.hasOwnProperty(key)) {
|
||||
result += ' ' + key + '="' + attributes[key] + '"';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function writeDeclaration (declaration, options) {
|
||||
return '<?xml' + writeAttributes(declaration[options.attributesKey]) + '?>';
|
||||
}
|
||||
|
||||
function writeComment (element, options) {
|
||||
return options.ignoreComment ? '' : '<!--' + element[options.commentKey] + '-->';
|
||||
}
|
||||
|
||||
function writeCdata (element, options) {
|
||||
return options.ignoreCdata ? '' : '<![CDATA[' + element[options.cdataKey] + ']]>';
|
||||
}
|
||||
|
||||
function writeText (element, options) {
|
||||
return options.ignoreText ? '' : element[options.textKey].replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function writeElement (element, options, depth) {
|
||||
var xml = '';
|
||||
xml += '<' + element.name;
|
||||
if (element[options.attributesKey]) {
|
||||
xml += writeAttributes(element[options.attributesKey]);
|
||||
}
|
||||
if (options.fullTagEmptyElement || (element[options.elementsKey] && element[options.elementsKey].length) || (element[options.attributesKey] && element[options.attributesKey]['xml:space'] === 'preserve')) {
|
||||
xml += '>';
|
||||
if (element[options.elementsKey] && element[options.elementsKey].length) {
|
||||
xml += writeElements(element[options.elementsKey], options, depth + 1);
|
||||
}
|
||||
xml += (options.spaces && element[options.elementsKey] && element[options.elementsKey].length && (element[options.elementsKey].length > 1 || element[options.elementsKey][0].type !== 'text') ? '\n' : '') + Array(depth + 1).join(options.spaces);
|
||||
xml += '</' + element.name + '>';
|
||||
} else {
|
||||
xml += '/>';
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
function writeElements (elements, options, depth, firstLine) {
|
||||
var indent = writeIndentation(options, depth, firstLine);
|
||||
return elements.reduce(function (xml, element) {
|
||||
switch (element.type) {
|
||||
case 'element': return xml + indent + writeElement(element, options, depth);
|
||||
case 'comment': return xml + indent + writeComment(element, options);
|
||||
case 'cdata': return xml + indent + writeCdata(element, options);
|
||||
case 'text': return xml + writeText(element, options);
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
|
||||
function hasContent (element, options, skipText) {
|
||||
var key;
|
||||
for (key in element) {
|
||||
if (element.hasOwnProperty(key)) {
|
||||
switch (key) {
|
||||
case options.textKey:
|
||||
if (!skipText) {
|
||||
return true;
|
||||
}
|
||||
break; // skip to next key
|
||||
case options.parentKey:
|
||||
case options.attributesKey:
|
||||
break; // skip to next key
|
||||
case options.cdataKey:
|
||||
case options.commentKey:
|
||||
case options.declarationKey:
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function writeElementCompact (element, name, options, depth, indent) {
|
||||
var xml = '';
|
||||
if (name) {
|
||||
xml += '<' + name;
|
||||
if (element[options.attributesKey]) {
|
||||
xml += writeAttributes(element[options.attributesKey]);
|
||||
}
|
||||
if (options.fullTagEmptyElement || hasContent(element, options) || element[options.attributesKey] && element[options.attributesKey]['xml:space'] === 'preserve') {
|
||||
xml += '>';
|
||||
} else {
|
||||
xml += '/>';
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
xml += writeElementsCompact(element, options, depth + 1, false);
|
||||
if (name) {
|
||||
xml += (indent ? writeIndentation(options, depth, false) : '') + '</' + name + '>';
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
function writeElementsCompact (element, options, depth, firstLine) {
|
||||
var key, xml = '';
|
||||
for (key in element) {
|
||||
if (element.hasOwnProperty(key)) {
|
||||
switch (key) {
|
||||
case options.declarationKey: xml += writeDeclaration(element[options.declarationKey], options); break;
|
||||
case options.attributesKey: case options.parentKey: break; // skip
|
||||
case options.textKey: xml += writeText(element, options); break;
|
||||
case options.cdataKey: xml += writeIndentation(options, depth, firstLine) + writeCdata(element, options); break;
|
||||
case options.commentKey: xml += writeIndentation(options, depth, firstLine) + writeComment(element, options); break;
|
||||
default: xml += writeIndentation(options, depth, firstLine) + writeElementCompact(element[key], key, options, depth, hasContent(element[key], options, true));
|
||||
}
|
||||
firstLine = firstLine && !xml;
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
module.exports = function (js, options) {
|
||||
'use strict';
|
||||
options = validateOptions(options);
|
||||
var xml = '';
|
||||
if (options.compact) {
|
||||
xml = writeElementsCompact(js, options, 0, true);
|
||||
} else {
|
||||
if (js[options.declarationKey]) {
|
||||
xml += writeDeclaration(js[options.declarationKey], options);
|
||||
}
|
||||
if (js[options.elementsKey] && js[options.elementsKey].length) {
|
||||
xml += writeElements(js[options.elementsKey], options, 0, !xml);
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
};
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*jslint node:true */
|
||||
var js2xml = require('./js2xml.js');
|
||||
|
||||
module.exports = function (json, options) {
|
||||
'use strict';
|
||||
if (json instanceof Buffer) {
|
||||
json = json.toString();
|
||||
}
|
||||
var js = null;
|
||||
if (typeof (json) === 'string') {
|
||||
try {
|
||||
js = JSON.parse(json);
|
||||
} catch (e) {
|
||||
throw new Error("The JSON structure is invalid");
|
||||
}
|
||||
} else {
|
||||
js = json;
|
||||
}
|
||||
return js2xml(js, options);
|
||||
};
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
/*jslint node:true */
|
||||
var sax = require('sax');
|
||||
var expat /*= require('node-expat');*/ = {on: function () {}, parse: function () {}};
|
||||
var common = require('./common');
|
||||
|
||||
var options;
|
||||
var pureJsParser = 1; //true;
|
||||
var currentElement;
|
||||
|
||||
function validateOptions (userOptions) {
|
||||
options = common.copyOptions(userOptions);
|
||||
common.ensureFlagExists('ignoreDeclaration', options);
|
||||
common.ensureFlagExists('ignoreAttributes', options);
|
||||
common.ensureFlagExists('ignoreText', options);
|
||||
common.ensureFlagExists('ignoreComment', options);
|
||||
common.ensureFlagExists('ignoreCdata', options);
|
||||
common.ensureFlagExists('compact', options);
|
||||
common.ensureFlagExists('alwaysChildren', options);
|
||||
common.ensureFlagExists('addParent', options);
|
||||
common.ensureFlagExists('trim', options);
|
||||
common.ensureFlagExists('nativeType', options);
|
||||
common.ensureFlagExists('sanitize', options);
|
||||
common.ensureKeyExists('declaration', options);
|
||||
common.ensureKeyExists('attributes', options);
|
||||
common.ensureKeyExists('text', options);
|
||||
common.ensureKeyExists('comment', options);
|
||||
common.ensureKeyExists('cdata', options);
|
||||
common.ensureKeyExists('type', options);
|
||||
common.ensureKeyExists('name', options);
|
||||
common.ensureKeyExists('elements', options);
|
||||
common.ensureKeyExists('parent', options);
|
||||
return options;
|
||||
}
|
||||
|
||||
function nativeType (value) {
|
||||
var nValue = Number(value);
|
||||
if (!isNaN(nValue)) {
|
||||
return nValue;
|
||||
}
|
||||
var bValue = value.toLowerCase();
|
||||
if (bValue === 'true') {
|
||||
return true;
|
||||
} else if (bValue === 'false') {
|
||||
return false;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function addField (type, value, options) {
|
||||
if (options.compact) {
|
||||
currentElement[options[type + 'Key']] = (currentElement[options[type + 'Key']] ? currentElement[options[type + 'Key']] + '\n' : '') + value;
|
||||
} else {
|
||||
if (!currentElement[options.elementsKey]) {
|
||||
currentElement[options.elementsKey] = [];
|
||||
}
|
||||
var element = {};
|
||||
element[options.typeKey] = type;
|
||||
element[options[type + 'Key']] = value;
|
||||
if (options.addParent) {
|
||||
element[options.parentKey] = currentElement;
|
||||
}
|
||||
currentElement[options.elementsKey].push(element);
|
||||
}
|
||||
}
|
||||
|
||||
function onDeclaration (declaration) {
|
||||
if (options.ignoreDeclaration) {
|
||||
return;
|
||||
}
|
||||
if (currentElement[options.declarationKey]) {
|
||||
return;
|
||||
}
|
||||
currentElement[options.declarationKey] = {};
|
||||
while (declaration.body) {
|
||||
var attribute = declaration.body.match(/([\w:-]+)\s*=\s*"([^"]*)"|'([^']*)'|(\w+)\s*/);
|
||||
if (!attribute) {
|
||||
break;
|
||||
}
|
||||
if (!currentElement[options.declarationKey][options.attributesKey]) {
|
||||
currentElement[options.declarationKey][options.attributesKey] = {};
|
||||
}
|
||||
currentElement[options.declarationKey][options.attributesKey][attribute[1]] = attribute[2];
|
||||
declaration.body = declaration.body.slice(attribute[0].length); // advance the string
|
||||
}
|
||||
if (options.addParent && options.compact) {
|
||||
currentElement[options.declarationKey][options.parentKey] = currentElement;
|
||||
}
|
||||
//console.error('result[options.declarationKey]', result[options.declarationKey]);
|
||||
}
|
||||
|
||||
function onStartElement (name, attributes) {
|
||||
var key, element;
|
||||
if (typeof name === 'object') {
|
||||
attributes = name.attributes;
|
||||
name = name.name;
|
||||
}
|
||||
if (options.trim && attributes) {
|
||||
for (key in attributes) {
|
||||
if (attributes.hasOwnProperty(key)) {
|
||||
attributes[key] = attributes[key].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.compact) {
|
||||
element = {};
|
||||
if (!options.ignoreAttributes && attributes && Object.keys(attributes).length) {
|
||||
element[options.attributesKey] = {};
|
||||
for (key in attributes) {
|
||||
if (attributes.hasOwnProperty(key)) {
|
||||
element[options.attributesKey][key] = attributes[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
element[options.parentKey] = currentElement;
|
||||
if (!(name in currentElement)) {
|
||||
currentElement[name] = element;
|
||||
} else {
|
||||
if (!(currentElement[name] instanceof Array)) {
|
||||
currentElement[name] = [currentElement[name]];
|
||||
}
|
||||
currentElement[name].push(element);
|
||||
}
|
||||
currentElement = element;
|
||||
} else {
|
||||
if (!currentElement[options.elementsKey]) {
|
||||
currentElement[options.elementsKey] = [];
|
||||
}
|
||||
element = {};
|
||||
element[options.typeKey] = 'element';
|
||||
element[options.nameKey] = name;
|
||||
if (!options.ignoreAttributes && attributes && Object.keys(attributes).length) {
|
||||
element[options.attributesKey] = attributes;
|
||||
}
|
||||
element[options.parentKey] = currentElement;
|
||||
if (options.alwaysChildren) {
|
||||
element[options.elementsKey] = [];
|
||||
}
|
||||
currentElement[options.elementsKey].push(element);
|
||||
currentElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
function onText (text) {
|
||||
//console.log('currentElement:', currentElement);
|
||||
if (options.ignoreText) {
|
||||
return;
|
||||
}
|
||||
if (!text.trim()) {
|
||||
return;
|
||||
}
|
||||
if (options.trim) {
|
||||
text = text.trim();
|
||||
}
|
||||
if (options.nativeType) {
|
||||
text = nativeType(text);
|
||||
}
|
||||
if (options.sanitize) {
|
||||
text = common.sanitize(text);
|
||||
}
|
||||
addField('text', text, options);
|
||||
}
|
||||
|
||||
function onComment (comment) {
|
||||
if (options.ignoreComment) {
|
||||
return;
|
||||
}
|
||||
if (options.trim) {
|
||||
comment = comment.trim();
|
||||
}
|
||||
if (options.sanitize) {
|
||||
comment = common.sanitize(comment);
|
||||
}
|
||||
addField('comment', comment, options);
|
||||
}
|
||||
|
||||
function onEndElement (name) {
|
||||
var parentElement = currentElement[options.parentKey];
|
||||
if (!options.addParent) {
|
||||
delete currentElement[options.parentKey];
|
||||
}
|
||||
currentElement = parentElement;
|
||||
}
|
||||
|
||||
function onCdata (cdata) {
|
||||
if (options.ignoreCdata) {
|
||||
return;
|
||||
}
|
||||
if (options.trim) {
|
||||
cdata = cdata.trim();
|
||||
}
|
||||
addField('cdata', cdata, options);
|
||||
}
|
||||
|
||||
function onError (error) {
|
||||
error.note = error; //console.error(error);
|
||||
}
|
||||
|
||||
module.exports = function (xml, userOptions) {
|
||||
|
||||
var parser = pureJsParser ? sax.parser(true, {}) : parser = new expat.Parser('UTF-8');
|
||||
var result = {};
|
||||
currentElement = result;
|
||||
|
||||
options = validateOptions(userOptions);
|
||||
|
||||
if (pureJsParser) {
|
||||
parser.onopentag = onStartElement;
|
||||
parser.ontext = onText;
|
||||
parser.oncomment = onComment;
|
||||
parser.onclosetag = onEndElement;
|
||||
parser.onerror = onError;
|
||||
parser.oncdata = onCdata;
|
||||
parser.onprocessinginstruction = onDeclaration;
|
||||
} else {
|
||||
parser.on('startElement', onStartElement);
|
||||
parser.on('text', onText);
|
||||
parser.on('comment', onComment);
|
||||
parser.on('endElement', onEndElement);
|
||||
parser.on('error', onError);
|
||||
//parser.on('startCdata', onStartCdata);
|
||||
//parser.on('endCdata', onEndCdata);
|
||||
//parser.on('entityDecl', onEntityDecl);
|
||||
}
|
||||
|
||||
if (pureJsParser) {
|
||||
parser.write(xml).close();
|
||||
} else {
|
||||
if (!parser.parse(xml)) {
|
||||
throw new Error('XML parsing error: ' + parser.getError());
|
||||
}
|
||||
}
|
||||
|
||||
if (result[options.elementsKey]) {
|
||||
var temp = result[options.elementsKey];
|
||||
delete result[options.elementsKey];
|
||||
result[options.elementsKey] = temp;
|
||||
delete result.text;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*jslint node:true */
|
||||
var common = require('./common');
|
||||
var xml2js = require('./xml2js');
|
||||
|
||||
function validateOptions (userOptions) {
|
||||
var options = common.copyOptions(userOptions);
|
||||
common.ensureSpacesExists(options);
|
||||
return options;
|
||||
}
|
||||
|
||||
module.exports = function(xml, userOptions) {
|
||||
'use strict';
|
||||
var options, js, json, parentKey;
|
||||
options = validateOptions(userOptions);
|
||||
js = xml2js(xml, options);
|
||||
parentKey = 'compact' in options && options.compact ? '_parent' : 'parent';
|
||||
if ('addParent' in options && options.addParent) {
|
||||
json = JSON.stringify(js, function (k, v) { return k === parentKey? '_' : v; }, options.spaces);
|
||||
} else {
|
||||
json = JSON.stringify(js, null, options.spaces);
|
||||
}
|
||||
return json.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
|
||||
};
|
||||
Reference in New Issue
Block a user