156 lines
7.2 KiB
JavaScript
156 lines
7.2 KiB
JavaScript
/*jslint node:true */
|
|
|
|
var cases = [
|
|
{
|
|
desc: 'declaration <?xml>',
|
|
xml: '<?xml?>',
|
|
js1: {"_declaration":{}},
|
|
js2: {"declaration":{}},
|
|
}, {
|
|
desc: 'declaration with attributes',
|
|
xml: '<?xml version="1.0" encoding="utf-8"?>',
|
|
js1: {"_declaration":{"_attributes":{"version":"1.0","encoding":"utf-8"}}},
|
|
js2: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8"}}},
|
|
}, {
|
|
desc: 'declaration and element',
|
|
xml: '<?xml?>\n<a/>',
|
|
js1: {"_declaration":{},"a":{}},
|
|
js2: {"declaration":{},"elements":[{"type":"element","name":"a"}]},
|
|
}, {
|
|
desc: 'declaration and elements',
|
|
xml: '<?xml?>\n<a>\n\v<b/>\n</a>',
|
|
js1: {"_declaration":{},"a":{"b":{}}},
|
|
js2: {"declaration":{},"elements":[{"type":"element","name":"a","elements":[{"type":"element","name":"b"}]}]},
|
|
}, {
|
|
desc: 'should convert comment',
|
|
xml: '<!-- \t Hello, World! \t -->',
|
|
js1: {"_comment":" \t Hello, World! \t "},
|
|
js2: {"elements":[{"type":"comment","comment":" \t Hello, World! \t "}]},
|
|
}, /*{
|
|
desc: 'should convert 2 comments',
|
|
xml: '<!-- \t Hello \t --><!-- \t World \t -->',
|
|
js1: {"_comment":[" \t Hello \t "," \t World \t "]},
|
|
js2: {"elements":[{"type":"comment","comment":" \t Hello \t "},{"type":"comment","comment":" \t World \t "}]},
|
|
}, */{
|
|
desc: 'should convert cdata',
|
|
xml: '<![CDATA[ \t <foo></bar> \t ]]>',
|
|
js1: {"_cdata":" \t <foo></bar> \t "},
|
|
js2: {"elements":[{"type":"cdata","cdata":" \t <foo></bar> \t "}]},
|
|
}, /*{
|
|
desc: 'should convert 2 cdata',
|
|
xml: '<![CDATA[ \t data]]><![CDATA[< > " and & \t ]]>',
|
|
js1: {"_cdata":[" \t data\n< > \" and & \t "]},
|
|
js2: {"elements":[{"type":"cdata","cdata":" \t data"},{"type":"cdata","cdata":"< > \" and & \t "}]},
|
|
}, */{
|
|
desc: 'should convert element',
|
|
xml: '<a/>',
|
|
js1: {"a":{}},
|
|
js2: {"elements":[{"type":"element","name":"a"}]},
|
|
}, {
|
|
desc: 'should convert 2 elements',
|
|
xml: '<a/><b/>',
|
|
js1: {"a":{},"b":{}},
|
|
js2: {"elements":[{"type":"element","name":"a"},{"type":"element","name":"b"}]},
|
|
}, {
|
|
desc: 'should convert attribute',
|
|
xml: '<a x="hello"/>',
|
|
js1: {"a":{_attributes:{"x":"hello"}}},
|
|
js2: {"elements":[{"type":"element","name":"a","attributes":{"x":"hello"}}]},
|
|
}, {
|
|
desc: 'should convert 2 attributes',
|
|
xml: '<a x="1.234" y="It\'s"/>',
|
|
js1: {"a":{_attributes:{"x":"1.234","y":"It\'s"}}},
|
|
js2: {"elements":[{"type":"element","name":"a","attributes":{"x":"1.234","y":"It\'s"}}]},
|
|
}, {
|
|
desc: 'should convert text in element',
|
|
xml: '<a> \t Hi \t </a>',
|
|
js1: {"a":{"_text":" \t Hi \t "}},
|
|
js2: {"elements":[{"type":"element","name":"a","elements":[{"type":"text","text":" \t Hi \t "}]}]},
|
|
}, {
|
|
desc: 'should convert multi-line text',
|
|
xml: '<a> Hi \n There \t </a>',
|
|
js1: {"a":{"_text":" Hi \n There \t "}},
|
|
js2: {"elements":[{"type":"element","name":"a","elements":[{"type":"text","text":" Hi \n There \t "}]}]},
|
|
}, {
|
|
desc: 'should convert nested elements',
|
|
xml: '<a>\n\v<b/>\n</a>',
|
|
js1: {"a":{"b":{}}},
|
|
js2: {"elements":[{"type":"element","name":"a","elements":[{"type":"element","name":"b"}]}]},
|
|
}, {
|
|
desc: 'should convert 3 nested elements',
|
|
xml: '<a>\n\v<b>\n\v\v<c/>\n\v</b>\n</a>',
|
|
js1: {"a":{"b":{"c":{}}}},
|
|
js2: {"elements":[{"type":"element","name":"a","elements":[{"type":"element","name":"b","elements":[{"type":"element","name":"c"}]}]}]},
|
|
}
|
|
];
|
|
|
|
module.exports = function (options) {
|
|
var i, tests = [];
|
|
options = options || {};
|
|
function applyOptions (obj) {
|
|
var key;
|
|
if (obj instanceof Array) {
|
|
obj.forEach(function (el) {
|
|
el = transform(el);
|
|
});
|
|
} else if (typeof obj === 'object') {
|
|
for (key in obj) {
|
|
if (key.indexOf('_') === 0 && obj[key] instanceof Array) {
|
|
obj[key] = obj[key].reduce(function (res, el) {
|
|
return (res === '' ? '' : res + '\n') + transform(el);
|
|
}, '');
|
|
} else {
|
|
if (key !== 'parent' && key !== '_parent') {
|
|
obj[key] = transform(obj[key]);
|
|
}
|
|
}
|
|
if (typeof obj[key] === 'object' && !(obj[key] instanceof Array)) {
|
|
if (options.compact && options.addParent && key !== '_attributes') {
|
|
if (options.compact) {obj[key]._parent = obj;} else {obj[key].parent = obj;}
|
|
}
|
|
}
|
|
}
|
|
if (!options.compact && options.addParent && obj.elements) {
|
|
obj.elements.forEach(function (el) {
|
|
el.parent = obj;
|
|
});
|
|
}
|
|
if (!options.compact && options.alwaysChildren && obj.type === 'element' && !obj.elements) {
|
|
obj.elements = [];
|
|
}
|
|
}
|
|
return obj;
|
|
function transform (x) {
|
|
if (x instanceof Array || typeof x === 'object') {
|
|
return applyOptions(x);
|
|
} else if (typeof x === 'string') {
|
|
return options.trim? x.trim() : x;
|
|
} else if (typeof x === 'number' || typeof x === 'boolean') {
|
|
return options.nativeType? x.toString() : x;
|
|
} else {
|
|
return x;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < cases.length; ++i) {
|
|
tests.push({desc: cases[i].desc, xml: null, js: null});
|
|
//tests[i].xml = options.singleLine ? cases[i].xml.replace(/\r\n|\r|\n|^\s+/gm, '') : cases[i].xml;
|
|
tests[i].xml = cases[i].xml;
|
|
if (!('spaces' in options) || options.spaces === 0 || typeof options.spaces === 'boolean') { tests[i].xml = tests[i].xml.replace(/>\n\v*/gm, '>'); }
|
|
if ('spaces' in options && options.spaces !== 0 && typeof options.spaces === 'number') { tests[i].xml = tests[i].xml.replace(/\v/g, Array(options.spaces + 1).join(' ')); }
|
|
if ('spaces' in options && typeof options.spaces === 'string') { tests[i].xml = tests[i].xml.replace(/\v/g, options.spaces); }
|
|
if (options.ignoreText) { tests[i].xml = tests[i].xml.replace(/>([\s\S]*?)</gm, '><'); }
|
|
if (options.ignoreComment) { tests[i].xml = tests[i].xml.replace(/<!--.*?-->/gm, ''); }
|
|
if (options.ignoreCdata) { tests[i].xml = tests[i].xml.replace(/<!\[CDATA\[.*?\]\]>/gm, ''); }
|
|
if (options.fullTagEmptyElement) { tests[i].xml = tests[i].xml.replace('<a/>', '<a></a>').replace('<b/>', '<b></b>').replace('<c/>', '<c></c>').replace('/>', '></a>'); }
|
|
if ('compact' in options && options.compact) {
|
|
tests[i].js = applyOptions(JSON.parse(JSON.stringify(cases[i].js1)));
|
|
} else {
|
|
tests[i].js = applyOptions(JSON.parse(JSON.stringify(cases[i].js2)));
|
|
}
|
|
}
|
|
if ('onlyItem' in options) {
|
|
tests = [tests[options.onlyItem]];
|
|
}
|
|
return tests;
|
|
}; |