diff --git a/README.md b/README.md index c3278f7e..2e7bf7ef 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,10 @@ value})``. Possible options are: * `mergeAttrs` (default: `false`): Merge attributes and child elements as properties of the parent, instead of keying attributes off a child attribute object. This option is ignored if `ignoreAttrs` is `true`. + * `mergeAttrsArray` (default: `true`): Ignored if `mergeAttrs` is `false`. + While merging attributes as properties of the parent (`mergeAttrs` is `true`), + when `mergeAttrsArray` is `false`, the value for an attribute is the raw value + rather than an array. * `validator` (default `null`): You can specify a callable that validates the resulting structure somehow, however you want. See unit tests for an example. diff --git a/lib/defaults.js b/lib/defaults.js index 0a21da0a..45877571 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -11,6 +11,7 @@ explicitArray: false, ignoreAttrs: false, mergeAttrs: false, + mergeAttrsArray: true, explicitRoot: false, validator: null, xmlns: false, @@ -36,6 +37,7 @@ explicitArray: true, ignoreAttrs: false, mergeAttrs: false, + mergeAttrsArray: true, explicitRoot: true, validator: null, xmlns: false, diff --git a/lib/parser.js b/lib/parser.js index 9e8261eb..049e24f2 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -152,7 +152,11 @@ newValue = _this.options.attrValueProcessors ? processItem(_this.options.attrValueProcessors, node.attributes[key], key) : node.attributes[key]; processedKey = _this.options.attrNameProcessors ? processItem(_this.options.attrNameProcessors, key) : key; if (_this.options.mergeAttrs) { - _this.assignOrPush(obj, processedKey, newValue); + if (_this.options.mergeAttrsArray) { + _this.assignOrPush(obj, processedKey, newValue); + } else { + obj[processedKey] = newValue; + } } else { obj[attrkey][processedKey] = newValue; } diff --git a/package.json b/package.json index e2425cc5..fb620bae 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,8 @@ "David Wood (http://codesleuth.co.uk/)", "Nicolas Maquet (https://github.com/nmaquet)", "Lovell Fuller (http://lovell.info/)", - "d3adc0d3 (https://github.com/d3adc0d3)" + "d3adc0d3 (https://github.com/d3adc0d3)", + "IRCraziestTaxi (https://github.com/IRCraziestTaxi)" ], "main": "./lib/xml2js", "files": [ diff --git a/src/defaults.coffee b/src/defaults.coffee index a9bd214b..03f6c143 100644 --- a/src/defaults.coffee +++ b/src/defaults.coffee @@ -17,6 +17,10 @@ exports.defaults = { # merge attributes and child elements onto parent object. this may # cause collisions. mergeAttrs: false + # when mergeAttrs and explicitArray are true + # and mergeAttrsArray is false (default true), + # do not parse attributes into an array. + mergeAttrsArray: true explicitRoot: false validator: null xmlns : false @@ -45,6 +49,10 @@ exports.defaults = { explicitArray: true ignoreAttrs: false mergeAttrs: false + # when mergeAttrs and explicitArray are true + # and mergeAttrsArray is false (default true), + # do not parse attributes into an array. + mergeAttrsArray: true explicitRoot: true validator: null xmlns : false diff --git a/src/parser.coffee b/src/parser.coffee index 8a375197..d1f0470d 100644 --- a/src/parser.coffee +++ b/src/parser.coffee @@ -111,7 +111,10 @@ class exports.Parser extends events.EventEmitter newValue = if @options.attrValueProcessors then processItem(@options.attrValueProcessors, node.attributes[key], key) else node.attributes[key] processedKey = if @options.attrNameProcessors then processItem(@options.attrNameProcessors, key) else key if @options.mergeAttrs - @assignOrPush obj, processedKey, newValue + if @options.mergeAttrsArray + @assignOrPush obj, processedKey, newValue + else + obj[processedKey] = newValue else obj[attrkey][processedKey] = newValue diff --git a/test/parser.test.coffee b/test/parser.test.coffee index 6d531d56..82aad8dd 100644 --- a/test/parser.test.coffee +++ b/test/parser.test.coffee @@ -107,6 +107,24 @@ module.exports = equ r.sample.listtest[0].single[0], 'Single' equ r.sample.listtest[0].attr[0], 'Attribute') + 'test parse with mergeAttrs and not mergeAttrsArray': skeleton(mergeAttrs: true, mergeAttrsArray: false, (r) -> + console.log 'Result object: ' + util.inspect r, false, 10 + equ r.sample.chartest[0].desc, 'Test for CHARs' + equ r.sample.chartest[0]._, 'Character data here!' + equ r.sample.cdatatest[0].desc, 'Test for CDATA' + equ r.sample.cdatatest[0].misc, 'true' + equ r.sample.cdatatest[0]._, 'CDATA here!' + equ r.sample.nochartest[0].desc, 'No data' + equ r.sample.nochartest[0].misc, 'false' + equ r.sample.listtest[0].item[0].subitem[0], 'Foo(1)' + equ r.sample.listtest[0].item[0].subitem[1], 'Foo(2)' + equ r.sample.listtest[0].item[0].subitem[2], 'Foo(3)' + equ r.sample.listtest[0].item[0].subitem[3], 'Foo(4)' + equ r.sample.listtest[0].item[1], 'Qux.' + equ r.sample.listtest[0].item[2], 'Quux.' + equ r.sample.listtest[0].single[0], 'Single' + equ r.sample.listtest[0].attr, 'Attribute') + 'test parse with mergeAttrs and not explicitArray': skeleton(mergeAttrs: true, explicitArray: false, (r) -> console.log 'Result object: ' + util.inspect r, false, 10 equ r.sample.chartest.desc, 'Test for CHARs'