Skip to content

Commit

Permalink
support arrayMode
Browse files Browse the repository at this point in the history
  • Loading branch information
amitguptagwl committed Oct 2, 2019
1 parent 306c514 commit ea25808
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 5 deletions.
193 changes: 193 additions & 0 deletions spec/arrayMode_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
"use strict";

const parser = require("../src/parser");

describe("XMLParser with array_mode enabled ", function () {
it("should parse all the tags as an array no matter how many occurences excluding premitive values when arrayMode is set to true", function () {
const xmlData = `<report>
<store>
<region>US</region>
<inventory>
<item grade="A">
<name dummy="attr">Banana</name>
<count>200</count>
</item>
<item grade="B">
<name>Apple</name>
<count>100</count>
</item>
</inventory>
</store>
<store>
<region>EU</region>
<inventory>
<item>
<name>Banana</name>
<count>100</count>
</item>
</inventory>
</store>
</report>`;

const expected = {
"report": [
{
"store": [
{
"region": "US",
"inventory": [
{
"item": [
{
"name": "Banana",
"count": 200
},
{
"name": "Apple",
"count": 100
}
]
}
]
},
{
"region": "EU",
"inventory": [
{
"item": [
{
"name": "Banana",
"count": 100
}
]
}
]
}
]
}
]
};

const result = parser.parse(xmlData, {
arrayMode: true,
ignoreAttributes: false,
});
//console.log(JSON.stringify(result, null, 4));
expect(result).toEqual(expected);
});

it("should parse all the tags as an array no matter how many occurences when arrayMode is set to strict", function () {
const xmlData = `<report>
<store>
<region>US</region>
<inventory>
<item grade="A">
<name dummy="attr">Banana</name>
<count>200</count>
</item>
<item grade="B">
<name>Apple</name>
<count>100</count>
</item>
</inventory>
</store>
<store>
<region>EU</region>
<inventory>
<item>
<name>Banana</name>
<count>100</count>
</item>
</inventory>
</store>
</report>`;

const expected = {
"report": [
{
"store": [
{
"region": ["US"],
"inventory": [
{
"item": [
{
"@_grade" : "A",
"name": ["Banana"],
"count": [200]
},
{
"@_grade" : "B",
"name": ["Apple"],
"count": [100]
}
]
}
]
},
{
"region": ["EU"],
"inventory": [
{
"item": [
{
"name": [ "Banana" ],
"count": [100]
}
]
}
]
}
]
}
]
};

const result = parser.parse(xmlData, {
arrayMode: "strict",
ignoreAttributes: false,
});
//console.log(JSON.stringify(result, null, 4));
expect(result).toEqual(expected);
});

it("try", function () {
const xmlData = `<report>
<store>
<region>US</region>
<inventory>
<item grade="A">some item detail
<name>Banana</name>
<count>200</count>
</item>
<item grade="B">
<![CDATA[som text]]>
<name>Apple</name>
<count>100</count>
</item>
</inventory>
</store>
</report>`;

let result = parser.parse(xmlData, {
arrayMode: true,
ignoreAttributes: false,
cdataTagName: "__cdata",
attrNodeName: "@@"
});
console.log(JSON.stringify(result, null, 4));
//expect(result).toEqual(expected);

result = parser.parse(xmlData, {
arrayMode: 'strict',
ignoreAttributes: false,
cdataTagName: "__cdata",
attrNodeName: "@@"
});
console.log(JSON.stringify(result, null, 4));
//expect(result).toEqual(expected);
});
});



20 changes: 17 additions & 3 deletions src/node2json.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ const convertToJson = function(node, options) {
//otherwise create a textnode if node has some text
if (util.isExist(node.val)) {
if (!(typeof node.val === 'string' && (node.val === '' || node.val === options.cdataPositionChar))) {
jObj[options.textNodeName] = node.val;
if(options.arrayMode === "strict"){
jObj[options.textNodeName] = [ node.val ];
}else{
jObj[options.textNodeName] = node.val;
}
}
}
}

util.merge(jObj, node.attrsMap);
util.merge(jObj, node.attrsMap, options.arrayMode);

const keys = Object.keys(node.child);
for (let index = 0; index < keys.length; index++) {
Expand All @@ -28,7 +32,17 @@ const convertToJson = function(node, options) {
jObj[tagname].push(convertToJson(node.child[tagname][tag], options));
}
} else {
jObj[tagname] = convertToJson(node.child[tagname][0], options);
if(options.arrayMode === true){
const result = convertToJson(node.child[tagname][0], options)
if(typeof result === 'object')
jObj[tagname] = [ result ];
else
jObj[tagname] = result;
}else if(options.arrayMode === "strict"){
jObj[tagname] = [convertToJson(node.child[tagname][0], options) ];
}else{
jObj[tagname] = convertToJson(node.child[tagname][0], options);
}
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,16 @@ exports.isEmptyObject = function(obj) {
* @param {*} target
* @param {*} a
*/
exports.merge = function(target, a) {
exports.merge = function(target, a, arrayMode) {
if (a) {
const keys = Object.keys(a); // will return an array of own properties
const len = keys.length; //don't make it inline
for (let i = 0; i < len; i++) {
target[keys[i]] = a[keys[i]];
if(arrayMode === 'strict'){
target[keys[i]] = [ a[keys[i]] ];
}else{
target[keys[i]] = a[keys[i]];
}
}
}
};
Expand Down

0 comments on commit ea25808

Please sign in to comment.