diff --git a/lib/xml.js b/lib/xml.js index 20b1310..e12806f 100644 --- a/lib/xml.js +++ b/lib/xml.js @@ -153,7 +153,7 @@ function resolve(data, indent, indent_count) { var attributes = [], content = []; - var isStringContent; + var hasStringContent = false; function get_attributes(obj){ var keys = Object.keys(obj); @@ -170,16 +170,8 @@ function resolve(data, indent, indent_count) { get_attributes(values._attr); } - if (values._cdata) { - content.push( - ('/g, ']]]]>') + ']]>' - ); - } - - if (values.forEach) { - isStringContent = false; - content.push(''); - values.forEach(function(value) { + if(values.forEach){ + values.forEach(function(value){ if (typeof value == 'object') { var _name = Object.keys(value)[0]; @@ -191,16 +183,31 @@ function resolve(data, indent, indent_count) { } } else { //string - content.pop(); - isStringContent=true; - content.push(escapeForXML(value)); + hasStringContent=true; + content.push(value); } - }); - if (!isStringContent) { + if(hasStringContent){ + content.forEach(function(part){ + if(typeof part == 'object') + part.isTextMode = true; + part.icount = 0; + part.indents = ''; + part.indent = ''; + }); + }else{ content.push(''); + content = content.map(function(value){ + return value.textNode? value.content[0]: value; + }); } } + + if (values._cdata) { + content.unshift( + ('/g, ']]]]>') + ']]>' + ); + } break; default: @@ -214,6 +221,7 @@ function resolve(data, indent, indent_count) { interrupt: interrupt, attributes: attributes, content: content, + isTextMode: hasStringContent, icount: indent_count, indents: indent_spaces, indent: indent @@ -238,7 +246,7 @@ function format(append, elem, end) { format(append, value); } - append(false, (len > 1 ? elem.indents : '') + append(false, (len > 1 && !elem.isTextMode ? elem.indents : '') + (elem.name ? '' : '') + (elem.indent && !end ? '\n' : '')); @@ -262,7 +270,7 @@ function format(append, elem, end) { + (elem.name ? '<' + elem.name : '') + (elem.attributes.length ? ' ' + elem.attributes.join(' ') : '') + (len ? (elem.name ? '>' : '') : (elem.name ? '/>' : '')) - + (elem.indent && len > 1 ? '\n' : '')); + + (!elem.isTextMode && elem.indent && len > 1 ? '\n' : '')); if (!len) { return append(false, elem.indent ? '\n' : ''); diff --git a/test/xml.test.js b/test/xml.test.js index 3286cf6..d6c2fe0 100644 --- a/test/xml.test.js +++ b/test/xml.test.js @@ -37,10 +37,19 @@ describe('xml module', function(done) { done(); }); + it('supports mixed xml and text nodes with whitespace', function(done) { + expect(xml([ { a: [ { foo1: '' }, { bar1: '' }, 'textNode', { foo2: '' }, { bar2: '' } ] } ])).to.equal('textNode'); + expect(xml([ { a: [ { foo1: ' ' }, { bar1: '' }, ' textNode ', { foo2: '' }, ' ', { bar2: '' } ] } ])).to.equal(' textNode '); + done(); + }); + it('indents property', function(done) { expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }], true)).to.equal('\n \n 1\n 2\n 3\n \n'); expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }], ' ')).to.equal('\n \n 1\n 2\n 3\n \n'); expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }], '\t')).to.equal('\n\t\n\t\t1\n\t\t2\n\t\t3\n\t\n'); + expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, 'textNode', { c: 3 } ] } ] }], true)).to.equal('\n 12textNode3\n'); + expect(xml([ { a: [ { b: [ ' textNode ', { c: 1 }, { c: 2 }, ' textNode ', { c: 3 }, ' textNode ' ] } ] }], ' ')).to.equal('\n textNode 12 textNode 3 textNode \n'); + expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, 'textNode ', { c: 3 } ] } ] }], '\t')).to.equal('\n\t12textNode 3\n'); expect(xml({guid:[{_attr:{premalink:true}},'content']},true)).to.equal('content'); done(); }); @@ -95,5 +104,4 @@ describe('xml module', function(done) { expect(xml([ { a: 'test' }], {})).to.equal('test'); done(); }); - }); \ No newline at end of file