diff --git a/README.md b/README.md index ca2b7647..c1426798 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,8 @@ var options = { arrayMode: false, //"strict" attrValueProcessor: (val, attrName) => he.decode(val, {isAttributeValue: true}),//default is a=>a tagValueProcessor : (val, tagName) => he.decode(val), //default is a=>a - stopNodes: ["parse-me-as-string"] + stopNodes: ["parse-me-as-string"], + alwaysCreateTextNode: false }; if( parser.validate(xmlData) === true) { //optional (it'll return an object in case it's not valid) @@ -201,7 +202,7 @@ Validator returns the following object in case of error; * **tagValueProcessor** : Process tag value during transformation. Like HTML decoding, word capitalization, etc. Applicable in case of string only. * **attrValueProcessor** : Process attribute value during transformation. Like HTML decoding, word capitalization, etc. Applicable in case of string only. * **stopNodes** : an array of tag names which are not required to be parsed. Instead their values are parsed as string. - +* **alwaysCreateTextNode** : When `true`, forces the parser always return a property for the `textNodeName` even if there are no attributes or node children.
diff --git a/spec/xmlParser_spec.js b/spec/xmlParser_spec.js index 756c1732..e355cb9d 100644 --- a/spec/xmlParser_spec.js +++ b/spec/xmlParser_spec.js @@ -885,4 +885,29 @@ describe("XMLParser", function() { }); expect(result).toEqual(expected); }); + + it("should create text node even if there are no attributes or node children", function() { + const xmlData = ` + value + 12345 + `; + const expected = { + "rootNode": { + "tag": { + "#text": "value" + }, + "tag2": { + "#text": 12345, + "@_some": "attribute" + }, + } + }; + + const result = parser.parse(xmlData, { + alwaysCreateTextNode : true, + ignoreAttributes: false, + parseAttributeValue: true + }); + expect(result).toEqual(expected); + }); }); diff --git a/src/node2json.js b/src/node2json.js index 7bbb5f81..75b45308 100644 --- a/src/node2json.js +++ b/src/node2json.js @@ -6,7 +6,7 @@ const convertToJson = function(node, options, parentTagName) { const jObj = {}; // when no child node or attr is present - if ((!node.child || util.isEmptyObject(node.child)) && (!node.attrsMap || util.isEmptyObject(node.attrsMap))) { + if (!options.alwaysCreateTextNode && (!node.child || util.isEmptyObject(node.child)) && (!node.attrsMap || util.isEmptyObject(node.attrsMap))) { return util.isExist(node.val) ? node.val : ''; } diff --git a/src/parser.d.ts b/src/parser.d.ts index 7a6c67ab..ea6f883b 100644 --- a/src/parser.d.ts +++ b/src/parser.d.ts @@ -16,6 +16,7 @@ type X2jOptions = { tagValueProcessor: (tagValue: string, tagName: string) => string; attrValueProcessor: (attrValue: string, attrName: string) => string; stopNodes: string[]; + alwaysCreateTextNode: boolean; }; type strnumOptions = { hex: boolean; diff --git a/src/xmlstr2xmlnode.js b/src/xmlstr2xmlnode.js index e59987d4..0a89f3a6 100644 --- a/src/xmlstr2xmlnode.js +++ b/src/xmlstr2xmlnode.js @@ -44,7 +44,8 @@ const defaultOptions = { attrValueProcessor: function(a, attrName) { return a; }, - stopNodes: [] + stopNodes: [], + alwaysCreateTextNode: false //decodeStrict: false, }; @@ -67,7 +68,8 @@ const props = [ 'attrValueProcessor', 'parseTrueNumberOnly', 'numParseOptions', - 'stopNodes' + 'stopNodes', + 'alwaysCreateTextNode' ]; exports.props = props;