diff --git a/src/builder.coffee b/src/builder.coffee
index 5653fde0..c8f7537a 100644
--- a/src/builder.coffee
+++ b/src/builder.coffee
@@ -71,14 +71,24 @@ class exports.Builder
# Case #3 Array data
else if Array.isArray child
+ # Simple-type children (numbers and strings) and complex children (objects and arrays) are converted
+ # differently. Arrays of simple children will repeat the parent element, e.g. `12`,
+ # while complex child arrays will be wrapped in their parent, e.g.
+ # `fuzbaz`
for own index, entry of child
- if typeof entry is 'string'
+ if typeof entry isnt 'object'
+ # single element, just append it as text
if @options.cdata && requiresCDATA entry
element = element.ele(key).raw(wrapCDATA entry).up()
else
element = element.ele(key, entry).up()
else
- element = render(element.ele(key), entry).up()
+ if (!arrayElement)
+ arrayElement = element.ele(key)
+ render(arrayElement, entry)
+ if (arrayElement)
+ element = arrayElement.up()
+ arrayElement = null
# Case #4 Objects
else if typeof child is "object"
diff --git a/test/builder.test.coffee b/test/builder.test.coffee
index e9c12be3..d8d02320 100644
--- a/test/builder.test.coffee
+++ b/test/builder.test.coffee
@@ -250,6 +250,38 @@ module.exports =
diffeq expected, actual
test.finish()
+ 'test attribute rendering': (test) ->
+ expected = """
+
+
+ 10
+
+
+ """
+ opts = cdata: true
+ builder = new xml2js.Builder opts
+ obj = {"xml":{
+ "$": {"foo": "bar"}
+ "MsgId":10}}
+ actual = builder.buildObject obj
+ diffeq expected, actual
+ test.finish()
+
+ 'test nested attribute rendering': (test) ->
+ expected = """
+
+
+ 10
+
+
+ """
+ opts = cdata: true
+ builder = new xml2js.Builder opts
+ obj = {"xml":{"MsgId":{"$": {"foo": "bar"}, "_": 10}}}
+ actual = builder.buildObject obj
+ diffeq expected, actual
+ test.finish()
+
'test does not error on array values when checking for cdata': (test) ->
expected = """
@@ -281,3 +313,24 @@ module.exports =
actual = builder.buildObject obj
diffeq expected, actual
test.finish()
+
+ 'test building obj with nested array': (test) ->
+ expected = """
+
+
+
+
+
+
+
+
+ """
+ opts = cdata: true
+ builder = new xml2js.Builder opts
+ obj = {request: { headers: [
+ { header: { '$': { 'method': 'INVITE', name: 'X-Mode', value: 'standard' } } },
+ { header: { '$': { 'method': 'INVITE', name: 'X-Prop', value: 'default' } } }
+ ]}}
+ actual = builder.buildObject obj
+ diffeq expected, actual
+ test.finish()