Skip to content

Commit

Permalink
support updateAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
amitguptagwl committed Apr 9, 2023
1 parent e2f1713 commit 5d4d846
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 7 deletions.
100 changes: 100 additions & 0 deletions spec/attr_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,4 +359,104 @@ id="7" data="foo bar" bug="true"/>`;
// console.log(output);
expect(output.replace(/\s+/g, "")).toEqual(XMLdata.replace(/\s+/g, ""));
});
it("should parse attributes with valid names", function() {
const xmlData = `<root>
<a keep="me" skip="me"></a>
<a skip="me"></a>
<a need="friend"></a>
<a camel="case" MakeMe="lower"></a>
<b change="val"></b>
</root>`;
const expected = {
"root": {
"a": [
{
"keep": "me"
},
"",
{
"need": "friend",
"friend": "me"
},
{
"Camel": "case",
"makeme": "lower"
}
],
"b": {
"change": "VAL"
}
}
};
const options = {
attributeNamePrefix: "",
ignoreAttributes: false,
parseAttributeValue: true,
updateAttributes(tagName, attrs, jPath){
if(attrs["skip"]) delete attrs["skip"]
if(attrs["camel"]) {
attrs["Camel"] = attrs["camel"];
delete attrs["camel"];
}
if(attrs["need"]) {
attrs["friend"] = "me";
}
if(attrs["MakeMe"]) {
attrs["makeme"] = attrs["MakeMe"];
delete attrs["MakeMe"];
}
if(attrs["change"]) {
attrs["change"] = attrs["change"].toUpperCase();
}
return attrs;
}
};

const parser = new XMLParser(options);
let result = parser.parse(xmlData);

// console.log(JSON.stringify(result,null,4));
expect(result).toEqual(expected);

result = XMLValidator.validate(xmlData);
expect(result).toBe(true);
});
it("should parse attributes with valid names", function() {
const xmlData = `<root>
<a keep="me" skip="me"></a>
<a skip="me"></a>
<a need="friend"></a>
<a camel="case" MakeMe="lower"></a>
<b change="val"></b>
</root>`;
const expected = {
"root": {
"a": [
"",
"",
"",
""
],
"b": ""
}
};
const options = {
attributeNamePrefix: "",
ignoreAttributes: false,
parseAttributeValue: true,
updateAttributes(tagName, attrs,jPath){
// console.log("called")
return null;
}
};

const parser = new XMLParser(options);
let result = parser.parse(xmlData);

// console.log(JSON.stringify(result,null,4));
expect(result).toEqual(expected);

result = XMLValidator.validate(xmlData);
expect(result).toBe(true);
});
});
1 change: 1 addition & 0 deletions src/fxp.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Control how tag value should be parsed. Called only if tag value is not empty
ignorePiTags: boolean;
transformTagName: ((tagName: string) => string) | false;
transformAttributeName: ((attributeName: string) => string) | false;
updateAttributes(tagName: string, jPath: string, attrs: {[k: string]: string}): {[k: string]: string};
};
type strnumOptions = {
hex: boolean;
Expand Down
3 changes: 3 additions & 0 deletions src/xmlparser/OptionsBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ const defaultOptions = {
ignorePiTags: false,
transformTagName: false,
transformAttributeName: false,
updateAttributes: function(tagName, attrs, jPath){
return attrs;
}
};

const buildOptions = function(options) {
Expand Down
14 changes: 7 additions & 7 deletions src/xmlparser/OrderedObjParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function resolveNameSpace(tagname) {
//const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm");
const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');

function buildAttributesMap(attrStr, jPath) {
function buildAttributesMap(attrStr, jPath, tagName) {
if (!this.options.ignoreAttributes && typeof attrStr === 'string') {
// attrStr = attrStr.replace(/\r?\n/g, ' ');
//attrStr = attrStr || attrStr.trim();
Expand Down Expand Up @@ -171,7 +171,7 @@ function buildAttributesMap(attrStr, jPath) {
attrCollection[this.options.attributesGroupName] = attrs;
return attrCollection;
}
return attrs;
return this.options.updateAttributes(tagName, attrs, jPath)
}
}

Expand Down Expand Up @@ -207,7 +207,7 @@ const parseXml = function(xmlData) {

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

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

if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath);
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName);
}
currentNode.addChild(childNode);

Expand Down Expand Up @@ -314,7 +314,7 @@ const parseXml = function(xmlData) {

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

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

if(tagName !== tagExp && attrExpPresent){
childNode[":@"] = this.buildAttributesMap(tagExp, jPath);
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
}
currentNode.addChild(childNode);
currentNode = childNode;
Expand Down

0 comments on commit 5d4d846

Please sign in to comment.