From 5e38a8037c0c1b983a80e213d7cadbddf422215c Mon Sep 17 00:00:00 2001 From: Erik Rothoff Andersson Date: Wed, 29 Jun 2022 21:32:41 +0200 Subject: [PATCH] Add transformTagName option to transform tag names when parsing --- spec/transform_tagname_spec.js | 36 +++++++++++++++++++++++++++++++ src/fxp.d.ts | 1 + src/xmlbuilder/json2xml.js | 3 ++- src/xmlparser/OptionsBuilder.js | 3 ++- src/xmlparser/OrderedObjParser.js | 13 ++++++++++- 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 spec/transform_tagname_spec.js diff --git a/spec/transform_tagname_spec.js b/spec/transform_tagname_spec.js new file mode 100644 index 00000000..73ddebfe --- /dev/null +++ b/spec/transform_tagname_spec.js @@ -0,0 +1,36 @@ +"use strict"; + +const {XMLParser} = require("../src/fxp"); + +describe("XMLParser", function() { + it("should parse lowercase tagnames", function() { + const xmlData = ` + + Person 1 + Person 2 + Person 3 + Person 4 + + `; + + const parser = new XMLParser({ + // transformTagName: (tagName) => tagName + ignoreDeclaration: true, + transformTagName: (tagName) => tagName.toLowerCase() + }); + let result = parser.parse(xmlData); + + const expected = { + "root": { + "person": [ + "Person 1", + "Person 2", + "Person 3", + "Person 4" + ] + } + }; + + expect(result).toEqual(expected); + }); +}); diff --git a/src/fxp.d.ts b/src/fxp.d.ts index 3169ac39..94e2f84b 100644 --- a/src/fxp.d.ts +++ b/src/fxp.d.ts @@ -22,6 +22,7 @@ type X2jOptions = { htmlEntities: boolean; ignoreDeclaration: boolean; ignorePiTags: boolean; + transformTagName: ((tagName: string) => string) | false; }; type strnumOptions = { hex: boolean; diff --git a/src/xmlbuilder/json2xml.js b/src/xmlbuilder/json2xml.js index ee4e6f2e..bb716a13 100644 --- a/src/xmlbuilder/json2xml.js +++ b/src/xmlbuilder/json2xml.js @@ -30,7 +30,8 @@ const defaultOptions = { { regex: new RegExp("\"", "g"), val: """ } ], processEntities: true, - stopNodes: [] + stopNodes: [], + transformTagName: false, }; function Builder(options) { diff --git a/src/xmlparser/OptionsBuilder.js b/src/xmlparser/OptionsBuilder.js index f46d0b21..b375d9dd 100644 --- a/src/xmlparser/OptionsBuilder.js +++ b/src/xmlparser/OptionsBuilder.js @@ -30,7 +30,8 @@ const defaultOptions = { processEntities: true, htmlEntities: false, ignoreDeclaration: false, - ignorePiTags: false + ignorePiTags: false, + transformTagName: false, }; const buildOptions = function(options) { diff --git a/src/xmlparser/OrderedObjParser.js b/src/xmlparser/OrderedObjParser.js index 141198f3..7342e632 100644 --- a/src/xmlparser/OrderedObjParser.js +++ b/src/xmlparser/OrderedObjParser.js @@ -193,6 +193,10 @@ const parseXml = function(xmlData) { } } + if(this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } + if(currentNode){ textData = this.saveTextToParentTag(textData, currentNode, jPath); } @@ -257,12 +261,15 @@ const parseXml = function(xmlData) { i = closeIndex + 2; }else {//Opening tag - let result = readTagExp(xmlData,i, this. options.removeNSPrefix); let tagName= result.tagName; let tagExp = result.tagExp; let attrExpPresent = result.attrExpPresent; let closeIndex = result.closeIndex; + + if (this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } //save text as child node if (currentNode && textData) { @@ -322,6 +329,10 @@ const parseXml = function(xmlData) { }else{ tagExp = tagExp.substr(0, tagExp.length - 1); } + + if(this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } const childNode = new xmlNode(tagName); if(tagName !== tagExp && attrExpPresent){