Skip to content

Commit fcedd31

Browse files
committed
fix #775: transformTagName with allowBooleanAttributes adds an unnecessary attribute
1 parent 54d2262 commit fcedd31

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

spec/transform_tagname_spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,52 @@ describe("XMLParser", function() {
3333

3434
expect(result).toEqual(expected);
3535
});
36+
it("should parse tag name with attributes", function() {
37+
const tagMap = { 'list-item': 'li' };
38+
const xmlData = `<?xml version="1.0"?>
39+
<root>
40+
<ul>
41+
<list-item/>
42+
<list-item>foo</list-item>
43+
<list-item checked>bar</list-item>
44+
<list-item attr="value">bar</list-item>
45+
</ul>
46+
</root>`
47+
const expected = {
48+
"?xml": {
49+
"@_version": "1.0"
50+
},
51+
"root": {
52+
"ul": {
53+
"li": [
54+
"",
55+
"foo",
56+
{
57+
"#text": "bar",
58+
"@_checked": true
59+
},
60+
{
61+
"#text": "bar",
62+
"@_attr": "value"
63+
}
64+
]
65+
}
66+
}
67+
}
68+
const options = {
69+
//preserveOrder: true,
70+
allowBooleanAttributes: true,
71+
ignoreAttributes: false,
72+
transformTagName: (tagName) => tagMap[tagName] ?? tagName,
73+
};
74+
const parser = new XMLParser(options);
75+
// console.log(JSON.stringify(parser.parse(xml)));
76+
77+
let result = parser.parse(xmlData);
78+
79+
// console.log(JSON.stringify(result,null,4));
80+
expect(result).toEqual(expected);
81+
82+
});
83+
3684
});

src/xmlparser/OrderedObjParser.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ function resolveNameSpace(tagname) {
140140
//const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm");
141141
const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');
142142

143-
function buildAttributesMap(attrStr, jPath, tagName) {
143+
function buildAttributesMap(attrStr, jPath) {
144144
if (this.options.ignoreAttributes !== true && typeof attrStr === 'string') {
145145
// attrStr = attrStr.replace(/\r?\n/g, ' ');
146146
//attrStr = attrStr || attrStr.trim();
@@ -252,14 +252,14 @@ const parseXml = function(xmlData) {
252252

253253
textData = this.saveTextToParentTag(textData, currentNode, jPath);
254254
if( (this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags){
255-
255+
//do nothing
256256
}else{
257257

258258
const childNode = new xmlNode(tagData.tagName);
259259
childNode.add(this.options.textNodeName, "");
260260

261261
if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){
262-
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
262+
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath);
263263
}
264264
this.addChild(currentNode, childNode, jPath, i);
265265
}
@@ -306,7 +306,12 @@ const parseXml = function(xmlData) {
306306
let closeIndex = result.closeIndex;
307307

308308
if (this.options.transformTagName) {
309-
tagName = this.options.transformTagName(tagName);
309+
//console.log(tagExp, tagName)
310+
const newTagName = this.options.transformTagName(tagName);
311+
if(tagExp === tagName) {
312+
tagExp = newTagName
313+
}
314+
tagName = newTagName;
310315
}
311316

312317
//save text as child node
@@ -357,7 +362,8 @@ const parseXml = function(xmlData) {
357362
const childNode = new xmlNode(tagName);
358363

359364
if(tagName !== tagExp && attrExpPresent){
360-
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
365+
childNode[":@"] = this.buildAttributesMap(tagExp, jPath
366+
);
361367
}
362368
if(tagContent) {
363369
tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
@@ -379,12 +385,16 @@ const parseXml = function(xmlData) {
379385
}
380386

381387
if(this.options.transformTagName) {
382-
tagName = this.options.transformTagName(tagName);
388+
const newTagName = this.options.transformTagName(tagName);
389+
if(tagExp === tagName) {
390+
tagExp = newTagName
391+
}
392+
tagName = newTagName;
383393
}
384394

385395
const childNode = new xmlNode(tagName);
386396
if(tagName !== tagExp && attrExpPresent){
387-
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
397+
childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
388398
}
389399
this.addChild(currentNode, childNode, jPath, startIndex);
390400
jPath = jPath.substr(0, jPath.lastIndexOf("."));
@@ -395,7 +405,7 @@ const parseXml = function(xmlData) {
395405
this.tagsNodeStack.push(currentNode);
396406

397407
if(tagName !== tagExp && attrExpPresent){
398-
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
408+
childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
399409
}
400410
this.addChild(currentNode, childNode, jPath, startIndex);
401411
currentNode = childNode;
@@ -416,6 +426,7 @@ function addChild(currentNode, childNode, jPath, startIndex){
416426
if (!this.options.captureMetaData) startIndex = undefined;
417427
const result = this.options.updateTag(childNode.tagname, jPath, childNode[":@"])
418428
if(result === false){
429+
//do nothing
419430
} else if(typeof result === "string"){
420431
childNode.tagname = result
421432
currentNode.addChild(childNode, startIndex);

0 commit comments

Comments
 (0)