Skip to content

Commit

Permalink
support entities by XMLBuilder for attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
amitguptagwl committed Nov 30, 2021
1 parent 259ecf3 commit 44d7de4
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 8 deletions.
55 changes: 52 additions & 3 deletions spec/doctype_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ describe("XMLParser Entities", function() {
expect(result).toEqual(expected);
});

it("should parse attributes having '>' in value", function() {
it("should build by decoding defaul entities", function() {
const jsObj = {
"note": {
"@heading": "Reminder > Alert",
"@heading": "Reminder > \"Alert",
"body": {
"#text": " 3 < 4",
"attr": "Writer: Donald Duck."
Expand All @@ -173,7 +173,7 @@ describe("XMLParser Entities", function() {
};

const expected = `
<note heading="Reminder > Alert">
<note heading="Reminder &gt; &quot;Alert">
<body>
3 &lt; 4
<attr>Writer: Donald Duck.</attr>
Expand All @@ -189,4 +189,53 @@ describe("XMLParser Entities", function() {
const result = builder.build(jsObj);
expect(result.replace(/\s+/g, "")).toEqual(expected.replace(/\s+/g, ""));
});
it("should build by decoding defaul entities in prserve mode", function() {
const jsObj = [
{
"note": [
{
"body": [
{
"#text": "3 < 4"
},
{
"attr": [
{
"#text": "Writer: Donald Duck."
}
]
}
]
}
],
"attributes": {
"@heading": "Reminder > \"Alert"
}
}
];

const expected = `
<note heading="Reminder &gt; &quot;Alert">
<body>
3 &lt; 4
<attr>Writer: Donald Duck.</attr>
</body>
</note>`;

const options = {
attributeNamePrefix: "@",
ignoreAttributes: false,
preserveOrder: true,
// processEntities: false
};

const parser = new XMLParser(options);
let result = parser.parse(expected);
// console.log(JSON.stringify(result,null,4));

const builder = new XMLBuilder(options);
result = builder.build(jsObj);
// console.log(result);
expect(result.replace(/\s+/g, "")).toEqual(expected.replace(/\s+/g, ""));
});
});
12 changes: 9 additions & 3 deletions src/xmlbuilder/json2xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ const defaultOptions = {
unpairedTags: [],
entities: {
">" : { regex: new RegExp(">", "g"), val: "&gt;" },
"<" : { regex: new RegExp("<", "g"), val: "&lt;" }
"<" : { regex: new RegExp("<", "g"), val: "&lt;" },
"sQuot" : { regex: new RegExp("\'", "g"), val: "&apos;" },
"dQuot" : { regex: new RegExp("\"", "g"), val: "&quot;" }
},
processEntities: true
};
Expand Down Expand Up @@ -114,7 +116,9 @@ Builder.prototype.j2x = function(jObj, level) {
//premitive type
const attr = this.isAttribute(key);
if (attr) {
attrStr += ' ' + attr + '="' + this.options.attributeValueProcessor(attr, '' + jObj[key]) + '"';
let val = this.options.attributeValueProcessor(attr, '' + jObj[key]);
val = this.replaceEntitiesValue(val);
attrStr += ' ' + attr + '="' + val + '"';
}else {
//tag value
if (key === this.options.textNodeName) {
Expand Down Expand Up @@ -145,7 +149,9 @@ Builder.prototype.j2x = function(jObj, level) {
const Ks = Object.keys(jObj[key]);
const L = Ks.length;
for (let j = 0; j < L; j++) {
attrStr += ' ' + Ks[j] + '="' + this.options.attributeValueProcessor(Ks[j], '' + jObj[key][Ks[j]]) + '"';
let val = this.options.attributeValueProcessor(Ks[j], '' + jObj[key][Ks[j]]);
val = this.replaceEntitiesValue(val);
attrStr += ' ' + Ks[j] + '="' + val + '"';
}
} else {
val += this.processTextOrObjNode(jObj[key], key, level)
Expand Down
17 changes: 15 additions & 2 deletions src/xmlbuilder/orderedJs2Xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ function arrToStr(arr, options, level){
const tagName = propName(tagObj);

if(tagName === options.textNodeName){
xmlStr += indentation + options.tagValueProcessor( tagName, tagObj[tagName]);
let tagText = options.tagValueProcessor( tagName, tagObj[tagName]);
tagText = replaceEntitiesValue(tagText, options);
xmlStr += indentation + tagText;
continue;
}else if( tagName === options.cdataPropName){
xmlStr += indentation + `<![CDATA[${tagObj[tagName][0][options.textNodeName]}]]>`;
Expand Down Expand Up @@ -62,10 +64,21 @@ function attr_to_str(attrMap, options){
let attrStr = "";
if(attrMap && !options.ignoreAttributes){
for( attr in attrMap){
attrStr+= ` ${attr.substr(options.attributeNamePrefix.length)}="${options.attributeValueProcessor(attr, attrMap[attr])}"`;
let attrVal = options.attributeValueProcessor(attr, attrMap[attr]);
attrVal = replaceEntitiesValue(attrVal, options);
attrStr+= ` ${attr.substr(options.attributeNamePrefix.length)}="${attrVal}"`;
}
}
return attrStr;
}

function replaceEntitiesValue(textValue, options){
if(textValue && textValue.length > 0 && options.processEntities){
for (const entityName in options.entities) {
const entity = options.entities[entityName];
textValue = textValue.replace(entity.regex, entity.val);
}
}
return textValue;
}
module.exports = toXml;

0 comments on commit 44d7de4

Please sign in to comment.