diff --git a/spec/unpairedTags_spec.js b/spec/unpairedTags_spec.js index 5ee83911..e1058927 100644 --- a/spec/unpairedTags_spec.js +++ b/spec/unpairedTags_spec.js @@ -274,5 +274,46 @@ describe("unpaired and empty tags", function() { // console.log(output); expect(output.replace(/\s+/g, "")).toEqual(expectedXmlData.replace(/\s+/g, "")); }); - + it("should construct jpath correctly for tag after unpaired tag", function() { + const xmlData = ` + + + + + + + + + + `; + + const jpaths = [ + "rootNode", + "rootNode.unpaired", + "rootNode.nested", + "rootNode.nested.unpaired", + "rootNode.nested.empty", + "rootNode.nested.unpaired", + "rootNode.empty", + "rootNode.stop", + "rootNode.unpaired", + ] + let jPathIndex=0; + const options = { + // format: true, + // preserveOrder: true, + ignoreAttributes: false, + stopNodes: ["stop"], + unpairedTags: ["unpaired", "unpaired2"], + updateTag: function(tagName,jpath){ + // console.log(jpath); + expect(jpath).toEqual(jpaths[jPathIndex++]); + return tagName; + } + }; + const parser = new XMLParser(options); + let result = parser.parse(xmlData); + // console.log(JSON.stringify(result, null,4)); + + }); }); diff --git a/src/xmlparser/OrderedObjParser.js b/src/xmlparser/OrderedObjParser.js index 4f9bfe8e..9af9f5e9 100644 --- a/src/xmlparser/OrderedObjParser.js +++ b/src/xmlparser/OrderedObjParser.js @@ -206,8 +206,17 @@ const parseXml = function(xmlData) { textData = this.saveTextToParentTag(textData, currentNode, jPath); } - jPath = jPath.substr(0, jPath.lastIndexOf(".")); - + //check if last tag of nested tag was unpaired tag + const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1); + let propIndex = 0 + if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){ + propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1) + if(propIndex < 1) propIndex = jPath.lastIndexOf("."); + }else{ + propIndex = jPath.lastIndexOf("."); + } + jPath = jPath.substring(0, propIndex); + currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope textData = ""; i = closeIndex; @@ -284,23 +293,22 @@ const parseXml = function(xmlData) { } } - if(tagName !== xmlObj.tagname){ - jPath += jPath ? "." + tagName : tagName; - } - //check if last tag was unpaired tag const lastTag = currentNode; if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){ currentNode = this.tagsNodeStack.pop(); + jPath = jPath.substring(0, jPath.lastIndexOf(".")); + } + if(tagName !== xmlObj.tagname){ + jPath += jPath ? "." + tagName : tagName; } - if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) { //TODO: namespace let tagContent = ""; //self-closing tag if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){ i = result.closeIndex; } - //boolean tag + //unpaired tag else if(this.options.unpairedTags.indexOf(tagName) !== -1){ i = result.closeIndex; } @@ -343,8 +351,8 @@ const parseXml = function(xmlData) { if(tagName !== tagExp && attrExpPresent){ childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName); } - jPath = jPath.substr(0, jPath.lastIndexOf(".")); this.addChild(currentNode, childNode, jPath) + jPath = jPath.substr(0, jPath.lastIndexOf(".")); } //opening tag else{