Skip to content

Commit d6c5630

Browse files
committed
fix jpath after unpaired node
1 parent 97713ad commit d6c5630

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

spec/unpairedTags_spec.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,5 +274,46 @@ describe("unpaired and empty tags", function() {
274274
// console.log(output);
275275
expect(output.replace(/\s+/g, "")).toEqual(expectedXmlData.replace(/\s+/g, ""));
276276
});
277-
277+
it("should construct jpath correctly for tag after unpaired tag", function() {
278+
const xmlData = `<rootNode>
279+
<unpaired>
280+
<nested>
281+
<unpaired>
282+
<empty />
283+
<unpaired>
284+
</nested>
285+
<empty />
286+
<stop />
287+
<unpaired>
288+
</rootNode>`;
289+
290+
const jpaths = [
291+
"rootNode",
292+
"rootNode.unpaired",
293+
"rootNode.nested",
294+
"rootNode.nested.unpaired",
295+
"rootNode.nested.empty",
296+
"rootNode.nested.unpaired",
297+
"rootNode.empty",
298+
"rootNode.stop",
299+
"rootNode.unpaired",
300+
]
301+
let jPathIndex=0;
302+
const options = {
303+
// format: true,
304+
// preserveOrder: true,
305+
ignoreAttributes: false,
306+
stopNodes: ["stop"],
307+
unpairedTags: ["unpaired", "unpaired2"],
308+
updateTag: function(tagName,jpath){
309+
// console.log(jpath);
310+
expect(jpath).toEqual(jpaths[jPathIndex++]);
311+
return tagName;
312+
}
313+
};
314+
const parser = new XMLParser(options);
315+
let result = parser.parse(xmlData);
316+
// console.log(JSON.stringify(result, null,4));
317+
318+
});
278319
});

src/xmlparser/OrderedObjParser.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,17 @@ const parseXml = function(xmlData) {
206206
textData = this.saveTextToParentTag(textData, currentNode, jPath);
207207
}
208208

209-
jPath = jPath.substr(0, jPath.lastIndexOf("."));
210-
209+
//check if last tag of nested tag was unpaired tag
210+
const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1);
211+
let propIndex = 0
212+
if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){
213+
propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1)
214+
if(propIndex < 1) propIndex = jPath.lastIndexOf(".");
215+
}else{
216+
propIndex = jPath.lastIndexOf(".");
217+
}
218+
jPath = jPath.substring(0, propIndex);
219+
211220
currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope
212221
textData = "";
213222
i = closeIndex;
@@ -284,23 +293,22 @@ const parseXml = function(xmlData) {
284293
}
285294
}
286295

287-
if(tagName !== xmlObj.tagname){
288-
jPath += jPath ? "." + tagName : tagName;
289-
}
290-
291296
//check if last tag was unpaired tag
292297
const lastTag = currentNode;
293298
if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){
294299
currentNode = this.tagsNodeStack.pop();
300+
jPath = jPath.substring(0, jPath.lastIndexOf("."));
301+
}
302+
if(tagName !== xmlObj.tagname){
303+
jPath += jPath ? "." + tagName : tagName;
295304
}
296-
297305
if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) { //TODO: namespace
298306
let tagContent = "";
299307
//self-closing tag
300308
if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){
301309
i = result.closeIndex;
302310
}
303-
//boolean tag
311+
//unpaired tag
304312
else if(this.options.unpairedTags.indexOf(tagName) !== -1){
305313
i = result.closeIndex;
306314
}
@@ -343,8 +351,8 @@ const parseXml = function(xmlData) {
343351
if(tagName !== tagExp && attrExpPresent){
344352
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
345353
}
346-
jPath = jPath.substr(0, jPath.lastIndexOf("."));
347354
this.addChild(currentNode, childNode, jPath)
355+
jPath = jPath.substr(0, jPath.lastIndexOf("."));
348356
}
349357
//opening tag
350358
else{

0 commit comments

Comments
 (0)