Skip to content

Commit 5d4d846

Browse files
committedApr 9, 2023
support updateAttributes
1 parent e2f1713 commit 5d4d846

File tree

4 files changed

+111
-7
lines changed

4 files changed

+111
-7
lines changed
 

‎spec/attr_spec.js

+100
Original file line numberDiff line numberDiff line change
@@ -359,4 +359,104 @@ id="7" data="foo bar" bug="true"/>`;
359359
// console.log(output);
360360
expect(output.replace(/\s+/g, "")).toEqual(XMLdata.replace(/\s+/g, ""));
361361
});
362+
it("should parse attributes with valid names", function() {
363+
const xmlData = `<root>
364+
<a keep="me" skip="me"></a>
365+
<a skip="me"></a>
366+
<a need="friend"></a>
367+
<a camel="case" MakeMe="lower"></a>
368+
<b change="val"></b>
369+
</root>`;
370+
const expected = {
371+
"root": {
372+
"a": [
373+
{
374+
"keep": "me"
375+
},
376+
"",
377+
{
378+
"need": "friend",
379+
"friend": "me"
380+
},
381+
{
382+
"Camel": "case",
383+
"makeme": "lower"
384+
}
385+
],
386+
"b": {
387+
"change": "VAL"
388+
}
389+
}
390+
};
391+
const options = {
392+
attributeNamePrefix: "",
393+
ignoreAttributes: false,
394+
parseAttributeValue: true,
395+
updateAttributes(tagName, attrs, jPath){
396+
if(attrs["skip"]) delete attrs["skip"]
397+
if(attrs["camel"]) {
398+
attrs["Camel"] = attrs["camel"];
399+
delete attrs["camel"];
400+
}
401+
if(attrs["need"]) {
402+
attrs["friend"] = "me";
403+
}
404+
if(attrs["MakeMe"]) {
405+
attrs["makeme"] = attrs["MakeMe"];
406+
delete attrs["MakeMe"];
407+
}
408+
if(attrs["change"]) {
409+
attrs["change"] = attrs["change"].toUpperCase();
410+
}
411+
return attrs;
412+
}
413+
};
414+
415+
const parser = new XMLParser(options);
416+
let result = parser.parse(xmlData);
417+
418+
// console.log(JSON.stringify(result,null,4));
419+
expect(result).toEqual(expected);
420+
421+
result = XMLValidator.validate(xmlData);
422+
expect(result).toBe(true);
423+
});
424+
it("should parse attributes with valid names", function() {
425+
const xmlData = `<root>
426+
<a keep="me" skip="me"></a>
427+
<a skip="me"></a>
428+
<a need="friend"></a>
429+
<a camel="case" MakeMe="lower"></a>
430+
<b change="val"></b>
431+
</root>`;
432+
const expected = {
433+
"root": {
434+
"a": [
435+
"",
436+
"",
437+
"",
438+
""
439+
],
440+
"b": ""
441+
}
442+
};
443+
const options = {
444+
attributeNamePrefix: "",
445+
ignoreAttributes: false,
446+
parseAttributeValue: true,
447+
updateAttributes(tagName, attrs,jPath){
448+
// console.log("called")
449+
return null;
450+
}
451+
};
452+
453+
const parser = new XMLParser(options);
454+
let result = parser.parse(xmlData);
455+
456+
// console.log(JSON.stringify(result,null,4));
457+
expect(result).toEqual(expected);
458+
459+
result = XMLValidator.validate(xmlData);
460+
expect(result).toBe(true);
461+
});
362462
});

‎src/fxp.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Control how tag value should be parsed. Called only if tag value is not empty
3232
ignorePiTags: boolean;
3333
transformTagName: ((tagName: string) => string) | false;
3434
transformAttributeName: ((attributeName: string) => string) | false;
35+
updateAttributes(tagName: string, jPath: string, attrs: {[k: string]: string}): {[k: string]: string};
3536
};
3637
type strnumOptions = {
3738
hex: boolean;

‎src/xmlparser/OptionsBuilder.js

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const defaultOptions = {
3434
ignorePiTags: false,
3535
transformTagName: false,
3636
transformAttributeName: false,
37+
updateAttributes: function(tagName, attrs, jPath){
38+
return attrs;
39+
}
3740
};
3841

3942
const buildOptions = function(options) {

‎src/xmlparser/OrderedObjParser.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ function resolveNameSpace(tagname) {
121121
//const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm");
122122
const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');
123123

124-
function buildAttributesMap(attrStr, jPath) {
124+
function buildAttributesMap(attrStr, jPath, tagName) {
125125
if (!this.options.ignoreAttributes && typeof attrStr === 'string') {
126126
// attrStr = attrStr.replace(/\r?\n/g, ' ');
127127
//attrStr = attrStr || attrStr.trim();
@@ -171,7 +171,7 @@ function buildAttributesMap(attrStr, jPath) {
171171
attrCollection[this.options.attributesGroupName] = attrs;
172172
return attrCollection;
173173
}
174-
return attrs;
174+
return this.options.updateAttributes(tagName, attrs, jPath)
175175
}
176176
}
177177

@@ -207,7 +207,7 @@ const parseXml = function(xmlData) {
207207

208208
jPath = jPath.substr(0, jPath.lastIndexOf("."));
209209

210-
currentNode = this.tagsNodeStack.pop();//avoid recurssion, set the parent tag scope
210+
currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope
211211
textData = "";
212212
i = closeIndex;
213213
} else if( xmlData[i+1] === '?') {
@@ -224,7 +224,7 @@ const parseXml = function(xmlData) {
224224
childNode.add(this.options.textNodeName, "");
225225

226226
if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){
227-
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath);
227+
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
228228
}
229229
currentNode.addChild(childNode);
230230

@@ -314,7 +314,7 @@ const parseXml = function(xmlData) {
314314

315315
const childNode = new xmlNode(tagName);
316316
if(tagName !== tagExp && attrExpPresent){
317-
childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
317+
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
318318
}
319319
if(tagContent) {
320320
tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
@@ -340,7 +340,7 @@ const parseXml = function(xmlData) {
340340

341341
const childNode = new xmlNode(tagName);
342342
if(tagName !== tagExp && attrExpPresent){
343-
childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
343+
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
344344
}
345345
jPath = jPath.substr(0, jPath.lastIndexOf("."));
346346
currentNode.addChild(childNode);
@@ -351,7 +351,7 @@ const parseXml = function(xmlData) {
351351
this.tagsNodeStack.push(currentNode);
352352

353353
if(tagName !== tagExp && attrExpPresent){
354-
childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
354+
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
355355
}
356356
currentNode.addChild(childNode);
357357
currentNode = childNode;

0 commit comments

Comments
 (0)
Please sign in to comment.