Skip to content

Commit 6511e07

Browse files
committed
fix unpaired tag
when unpaired tags appear in last of a nested tag. Also throw error when unpaired tag is used as closing tag
1 parent b6cad83 commit 6511e07

File tree

3 files changed

+118
-4
lines changed

3 files changed

+118
-4
lines changed

docs/v4/2.XMLparseOptions.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ const xmlDataStr = `
885885
<empty />
886886
<unpaired>
887887
<unpaired />
888-
<unpaired></unpaired>
888+
<unpaired>
889889
</rootNode>`;
890890

891891
const options = {
@@ -904,7 +904,7 @@ Output
904904
}
905905
}
906906
```
907-
907+
**Note**: Unpaired tag can't be used as closing tag e.g. `</unpaired>` is not allowed.
908908
## updateTag
909909

910910
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.

spec/unpairedTags_spec.js

+112-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe("unpaired and empty tags", function() {
8787
<unpaired>
8888
<unpaired />
8989
<unpaired>
90-
<unpaired></unpaired>
90+
<unpaired />
9191
<unpaired>
9292
</rootNode>`;
9393

@@ -317,3 +317,114 @@ describe("unpaired and empty tags", function() {
317317

318318
});
319319
});
320+
321+
describe("unpaired tas position", function() {
322+
it(" when appears last in nested tag", function() {
323+
const xmlData = `<root><a><u></a><b>w</b></root>`;
324+
const expected = {
325+
"root": {
326+
"a": {
327+
"u": "",
328+
},
329+
"b":"w"
330+
}
331+
};
332+
const options = {
333+
unpairedTags: ["u"]
334+
};
335+
const parser = new XMLParser(options);
336+
// const parser = new XMLParser({ updateTag});
337+
let result = parser.parse(xmlData);
338+
339+
// console.log(JSON.stringify(result,null,4));
340+
expect(result).toEqual(expected);
341+
342+
});
343+
it(" when unpair then unpair self closed", function() {
344+
const xmlData = `<root><v><v/><u></root>`;
345+
const expected = {
346+
"root": {
347+
"v": ["",""],
348+
"u": ""
349+
}
350+
}
351+
const options = {
352+
unpairedTags: ["u","v"]
353+
};
354+
const parser = new XMLParser(options);
355+
// const parser = new XMLParser({ updateTag});
356+
let result = parser.parse(xmlData);
357+
358+
// console.log(JSON.stringify(result,null,4));
359+
expect(result).toEqual(expected);
360+
361+
});
362+
it("when unpair then unpair", function() {
363+
const xmlData = `<root><v><v></root>`;
364+
const expected = {
365+
"root": {
366+
"v": ["",""]
367+
}
368+
}
369+
const options = {
370+
unpairedTags: ["u","v"]
371+
};
372+
const parser = new XMLParser(options);
373+
// const parser = new XMLParser({ updateTag});
374+
let result = parser.parse(xmlData);
375+
376+
// console.log(JSON.stringify(result,null,4));
377+
expect(result).toEqual(expected);
378+
379+
});
380+
it(" when 2 unpaired then unpaired self closed", function() {
381+
const xmlData = `<root><v><v><v/></root>`;
382+
const expected = {
383+
"root": {
384+
"v": ["","",""]
385+
}
386+
}
387+
const options = {
388+
unpairedTags: ["u","v"]
389+
};
390+
const parser = new XMLParser(options);
391+
// const parser = new XMLParser({ updateTag});
392+
let result = parser.parse(xmlData);
393+
394+
// console.log(JSON.stringify(result,null,4));
395+
expect(result).toEqual(expected);
396+
397+
});
398+
it(" when unpaired followed by normal self closed", function() {
399+
const xmlData = `<root><v><a/></root>`;
400+
const expected = {
401+
"root": {
402+
"v": "",
403+
"a": ""
404+
}
405+
}
406+
const options = {
407+
unpairedTags: ["u","v"]
408+
};
409+
const parser = new XMLParser(options);
410+
// const parser = new XMLParser({ updateTag});
411+
let result = parser.parse(xmlData);
412+
413+
// console.log(JSON.stringify(result,null,4));
414+
expect(result).toEqual(expected);
415+
416+
});
417+
it(" when unpaired is used as closing tag then it's error", function() {
418+
const xmlData = `<root><v><a/></v></root>`;
419+
const options = {
420+
unpairedTags: ["u","v"]
421+
};
422+
const parser = new XMLParser(options);
423+
424+
expect(() =>{
425+
parser.parse(xmlData);
426+
}).toThrowError("Unpaired tag can not be used as closing tag: </v>")
427+
428+
});
429+
430+
});

src/xmlparser/OrderedObjParser.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,13 @@ const parseXml = function(xmlData) {
208208

209209
//check if last tag of nested tag was unpaired tag
210210
const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1);
211+
if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){
212+
throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
213+
}
211214
let propIndex = 0
212215
if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){
213216
propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1)
214-
if(propIndex < 1) propIndex = jPath.lastIndexOf(".");
217+
this.tagsNodeStack.pop();
215218
}else{
216219
propIndex = jPath.lastIndexOf(".");
217220
}

0 commit comments

Comments
 (0)