From ec9173591fd023704204c24d6383465d2cd89dbf Mon Sep 17 00:00:00 2001 From: Amit Gupta Date: Wed, 16 Mar 2022 16:15:52 +0530 Subject: [PATCH] support commentPropName when order is not given --- docs/v4/3.XMLBuilder.md | 53 +++++++++++++++++++++++++++++++++++++- spec/comments_spec.js | 46 +++++++++++++++++++++++++++++++++ src/xmlbuilder/json2xml.js | 9 ++++--- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/docs/v4/3.XMLBuilder.md b/docs/v4/3.XMLBuilder.md index 9583ad7f..2cf83e21 100644 --- a/docs/v4/3.XMLBuilder.md +++ b/docs/v4/3.XMLBuilder.md @@ -113,7 +113,58 @@ Output It is recommended to use `preserveOrder: true` when you're parsing XML to js object and building the XML back. So that the order of CDATA is maintained. ## commentPropName -To recognize commentsin a JS object so that they can be transformed correcty. This option is supported only if `preserveOrder: true` because position of comment is important. +To recognize comments in a JS object so that they can be transformed correcty. + + +Eg +Input +```json +{ + "any_name": { + "person": { + "phone": [ + 122233344550, + 122233344551, + "" + ], + "name": [ + "JackJack", + "Mohan" + ], + "blank": "", + "regx": "^[ ].*$" + } + } + }; +``` +code +```js +const options = { + processEntities:false, + format: true, + ignoreAttributes: false, + commentPropName: "phone" +}; + +const builder = new XMLBuilder(options); +const xmlOutput = builder.build(input); +``` +Output +```xml + + + + + + JackJack + Mohan + + ^[ ].*$ + +`; +``` + +It is recommended to use `preserveOrder: true` when you're parsing XML to js object and building the XML back. So that the order of comment is maintained. ## format By default, parsed XML is single line XML string. By `format: true`, you can format it for better view. diff --git a/spec/comments_spec.js b/spec/comments_spec.js index 859c50d7..a7e244aa 100644 --- a/spec/comments_spec.js +++ b/spec/comments_spec.js @@ -33,7 +33,53 @@ describe("Comments", function() { expect(output.replace(/\s+/g, "")).toEqual(XMLdata.replace(/\s+/g, "")); }); +it("should build XML with Comments without parseOrder", function() { + const input = { + "any_name": { + "person": { + "phone": [ + 122233344550, + 122233344551, + "" + ], + "name": [ + `JackJack`, + `Mohan` + ], + "blank": "", + "another": { + "phone": "1245789", + } + } + } + }; + const expected = ` + + + + + + JackJack + Mohan + + + + + + `; + + const options = { + processEntities:false, + format: true, + ignoreAttributes: false, + commentPropName: "phone" + }; + const builder = new XMLBuilder(options); + const xmlOutput = builder.build(input); + // console.log(xmlOutput); + expect(xmlOutput.replace(/\s+/g, "")).toEqual(expected.replace(/\s+/g, "")); +}); }); diff --git a/src/xmlbuilder/json2xml.js b/src/xmlbuilder/json2xml.js index 448eba53..ee4e6f2e 100644 --- a/src/xmlbuilder/json2xml.js +++ b/src/xmlbuilder/json2xml.js @@ -173,7 +173,9 @@ function buildObjectNode(val, key, attrStr, level) { if (attrStr && val.indexOf('<') === -1) { return ( this.indentate(level) + '<' + key + attrStr + piClosingChar + '>' + val + tagEndExp ); - } else { + } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) { + return this.indentate(level) + `` + this.newLine; + }else { return ( this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar + val + @@ -192,8 +194,9 @@ function buildEmptyObjNode(val, key, attrStr, level) { function buildTextValNode(val, key, attrStr, level) { if (this.options.cdataPropName !== false && key === this.options.cdataPropName) { - if(this.options.format) return this.indentate(level) + `\n`; - else return this.indentate(level) + ``; + return this.indentate(level) + `` + this.newLine; + }else if (this.options.commentPropName !== false && key === this.options.commentPropName) { + return this.indentate(level) + `` + this.newLine; }else{ let textValue = this.options.tagValueProcessor(key, val); textValue = this.replaceEntitiesValue(textValue);