diff --git a/docs/v4/2.XMLparseOptions.md b/docs/v4/2.XMLparseOptions.md index be66db7a..407dff35 100644 --- a/docs/v4/2.XMLparseOptions.md +++ b/docs/v4/2.XMLparseOptions.md @@ -885,7 +885,7 @@ const xmlDataStr = ` - + `; const options = { @@ -904,7 +904,7 @@ Output } } ``` - +**Note**: Unpaired tag can't be used as closing tag e.g. `` is not allowed. ## updateTag This property allow you to change tag name when you send different name, skip a tag from the parsing result when you return false, or to change attributes. diff --git a/spec/unpairedTags_spec.js b/spec/unpairedTags_spec.js index e1058927..ff5c1f82 100644 --- a/spec/unpairedTags_spec.js +++ b/spec/unpairedTags_spec.js @@ -87,7 +87,7 @@ describe("unpaired and empty tags", function() { - + `; @@ -317,3 +317,114 @@ describe("unpaired and empty tags", function() { }); }); + +describe("unpaired tas position", function() { + it(" when appears last in nested tag", function() { + const xmlData = `w`; + const expected = { + "root": { + "a": { + "u": "", + }, + "b":"w" + } + }; + const options = { + unpairedTags: ["u"] + }; + const parser = new XMLParser(options); + // const parser = new XMLParser({ updateTag}); + let result = parser.parse(xmlData); + + // console.log(JSON.stringify(result,null,4)); + expect(result).toEqual(expected); + + }); + it(" when unpair then unpair self closed", function() { + const xmlData = ``; + const expected = { + "root": { + "v": ["",""], + "u": "" + } + } + const options = { + unpairedTags: ["u","v"] + }; + const parser = new XMLParser(options); + // const parser = new XMLParser({ updateTag}); + let result = parser.parse(xmlData); + + // console.log(JSON.stringify(result,null,4)); + expect(result).toEqual(expected); + + }); + it("when unpair then unpair", function() { + const xmlData = ``; + const expected = { + "root": { + "v": ["",""] + } + } + const options = { + unpairedTags: ["u","v"] + }; + const parser = new XMLParser(options); + // const parser = new XMLParser({ updateTag}); + let result = parser.parse(xmlData); + + // console.log(JSON.stringify(result,null,4)); + expect(result).toEqual(expected); + + }); + it(" when 2 unpaired then unpaired self closed", function() { + const xmlData = ``; + const expected = { + "root": { + "v": ["","",""] + } + } + const options = { + unpairedTags: ["u","v"] + }; + const parser = new XMLParser(options); + // const parser = new XMLParser({ updateTag}); + let result = parser.parse(xmlData); + + // console.log(JSON.stringify(result,null,4)); + expect(result).toEqual(expected); + + }); + it(" when unpaired followed by normal self closed", function() { + const xmlData = ``; + const expected = { + "root": { + "v": "", + "a": "" + } + } + const options = { + unpairedTags: ["u","v"] + }; + const parser = new XMLParser(options); + // const parser = new XMLParser({ updateTag}); + let result = parser.parse(xmlData); + + // console.log(JSON.stringify(result,null,4)); + expect(result).toEqual(expected); + + }); + it(" when unpaired is used as closing tag then it's error", function() { + const xmlData = ``; + const options = { + unpairedTags: ["u","v"] + }; + const parser = new XMLParser(options); + + expect(() =>{ + parser.parse(xmlData); + }).toThrowError("Unpaired tag can not be used as closing tag: ") + + }); + +}); diff --git a/src/xmlparser/OrderedObjParser.js b/src/xmlparser/OrderedObjParser.js index 9af9f5e9..db11a8c0 100644 --- a/src/xmlparser/OrderedObjParser.js +++ b/src/xmlparser/OrderedObjParser.js @@ -208,10 +208,13 @@ const parseXml = function(xmlData) { //check if last tag of nested tag was unpaired tag const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1); + if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){ + throw new Error(`Unpaired tag can not be used as closing tag: `); + } let propIndex = 0 if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){ propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1) - if(propIndex < 1) propIndex = jPath.lastIndexOf("."); + this.tagsNodeStack.pop(); }else{ propIndex = jPath.lastIndexOf("."); }