From 1c2d4eb15e03aded143d45ee9d74840f5d5ca492 Mon Sep 17 00:00:00 2001 From: Ralph Leermakers Date: Thu, 1 May 2014 12:34:16 +0200 Subject: [PATCH 1/2] fix #14 mixed bug in mixed xml and text content --- lib/xml.js | 38 +++++++++++++++++++++++++------------- test/xml.test.js | 12 ++++++++---- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lib/xml.js b/lib/xml.js index 20b1310..d02ecc9 100644 --- a/lib/xml.js +++ b/lib/xml.js @@ -153,7 +153,8 @@ function resolve(data, indent, indent_count) { var attributes = [], content = []; - var isStringContent; + var isStringContentOnly, + hasContent; function get_attributes(obj){ var keys = Object.keys(obj); @@ -170,15 +171,9 @@ function resolve(data, indent, indent_count) { get_attributes(values._attr); } - if (values._cdata) { - content.push( - ('/g, ']]]]>') + ']]>' - ); - } - if (values.forEach) { - isStringContent = false; - content.push(''); + isStringContentOnly = true; + hasContent = false; values.forEach(function(value) { if (typeof value == 'object') { var _name = Object.keys(value)[0]; @@ -186,21 +181,38 @@ function resolve(data, indent, indent_count) { if (_name == '_attr') { get_attributes(value._attr); } else { + isStringContentOnly=false; + hasContent = true; content.push(resolve( value, indent, indent_count + 1)); } } else { //string - content.pop(); - isStringContent=true; - content.push(escapeForXML(value)); + hasContent = true; + var textNode = resolve( + value, indent, indent_count + 1); + textNode.textNode = true; + content.push(textNode); } }); - if (!isStringContent) { + if (!isStringContentOnly) { + content.unshift(''); + content.push(''); + }else if(!hasContent){ content.push(''); + }else{ + content = content.map(function(value){ + return value.textNode? value.content[0]: value; + }); } } + + if (values._cdata) { + content.unshift( + ('/g, ']]]]>') + ']]>' + ); + } break; default: diff --git a/test/xml.test.js b/test/xml.test.js index 3286cf6..eecd266 100644 --- a/test/xml.test.js +++ b/test/xml.test.js @@ -37,10 +37,15 @@ describe('xml module', function(done) { done(); }); + it('supports mixed xml and text nodes', function(done) { + 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 \n 1\n 2\n textNode\n 3\n \n'); + expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, 'textNode', { c: 3 } ] } ] }], ' ')).to.equal('\n \n 1\n 2\n textNode\n 3\n \n'); + expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, 'textNode', { c: 3 } ] } ] }], '\t')).to.equal('\n\t\n\t\t1\n\t\t2\n\t\ttextNode\n\t\t3\n\t\n'); expect(xml({guid:[{_attr:{premalink:true}},'content']},true)).to.equal('content'); done(); }); @@ -95,5 +100,4 @@ describe('xml module', function(done) { expect(xml([ { a: 'test' }], {})).to.equal('test'); done(); }); - }); \ No newline at end of file From 9d9051aa4ffccc1ba480f6d759316f9008e20e2f Mon Sep 17 00:00:00 2001 From: Ralph Leermakers Date: Thu, 15 May 2014 11:55:07 +0200 Subject: [PATCH 2/2] when textNodes are present, no indentation should be added to preserve the original whitespace --- lib/xml.js | 38 +++++++++++++++++--------------------- test/xml.test.js | 12 ++++++++---- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lib/xml.js b/lib/xml.js index d02ecc9..e12806f 100644 --- a/lib/xml.js +++ b/lib/xml.js @@ -153,8 +153,7 @@ function resolve(data, indent, indent_count) { var attributes = [], content = []; - var isStringContentOnly, - hasContent; + var hasStringContent = false; function get_attributes(obj){ var keys = Object.keys(obj); @@ -171,37 +170,33 @@ function resolve(data, indent, indent_count) { get_attributes(values._attr); } - if (values.forEach) { - isStringContentOnly = true; - hasContent = false; - values.forEach(function(value) { + if(values.forEach){ + values.forEach(function(value){ if (typeof value == 'object') { var _name = Object.keys(value)[0]; if (_name == '_attr') { get_attributes(value._attr); } else { - isStringContentOnly=false; - hasContent = true; content.push(resolve( value, indent, indent_count + 1)); } } else { //string - hasContent = true; - var textNode = resolve( - value, indent, indent_count + 1); - textNode.textNode = true; - content.push(textNode); + hasStringContent=true; + content.push(value); } - }); - if (!isStringContentOnly) { - content.unshift(''); - content.push(''); - }else if(!hasContent){ - content.push(''); + 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; }); @@ -226,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 @@ -250,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' : '')); @@ -274,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 eecd266..d6c2fe0 100644 --- a/test/xml.test.js +++ b/test/xml.test.js @@ -37,15 +37,19 @@ describe('xml module', function(done) { done(); }); - it('supports mixed xml and text nodes', function(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 }, 'textNode', { c: 3 } ] } ] }], true)).to.equal('\n \n 1\n 2\n textNode\n 3\n \n'); - expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, 'textNode', { c: 3 } ] } ] }], ' ')).to.equal('\n \n 1\n 2\n textNode\n 3\n \n'); - expect(xml([ { a: [ { b: [ { c: 1 }, { c: 2 }, 'textNode', { c: 3 } ] } ] }], '\t')).to.equal('\n\t\n\t\t1\n\t\t2\n\t\ttextNode\n\t\t3\n\t\n'); + 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(); });