fast-xml-parser
Advanced tools
Comparing version 4.0.1 to 4.0.2
Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library. | ||
**4.0.2 / 2022-02-04** | ||
* builder supports `suppressUnpairedNode` | ||
* parser supports `ignoreDeclaration` and `ignorePiTags` | ||
* fix: when comment is parsed as text value if given as `<!--> ...` #423 | ||
* builder supports decoding `&` | ||
**4.0.1 / 2022-01-08** | ||
@@ -4,0 +10,0 @@ * fix builder for pi tag |
{ | ||
"name": "fast-xml-parser", | ||
"version": "4.0.1", | ||
"version": "4.0.2", | ||
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries", | ||
@@ -5,0 +5,0 @@ "main": "./src/fxp.js", |
@@ -23,2 +23,4 @@ type X2jOptions = { | ||
htmlEntities: boolean; | ||
ignoreDeclaration: boolean; | ||
ignorePiTags: boolean; | ||
}; | ||
@@ -48,2 +50,3 @@ type strnumOptions = { | ||
suppressEmptyNode: boolean; | ||
suppressUnpairedNode: boolean; | ||
suppressBooleanAttributes: boolean; | ||
@@ -50,0 +53,0 @@ preserveOrder: boolean; |
@@ -14,2 +14,3 @@ 'use strict'; | ||
suppressEmptyNode: false, | ||
suppressUnpairedNode: true, | ||
suppressBooleanAttributes: true, | ||
@@ -25,8 +26,9 @@ tagValueProcessor: function(key, a) { | ||
unpairedTags: [], | ||
entities: { | ||
">" : { regex: new RegExp(">", "g"), val: ">" }, | ||
"<" : { regex: new RegExp("<", "g"), val: "<" }, | ||
"sQuot" : { regex: new RegExp("\'", "g"), val: "'" }, | ||
"dQuot" : { regex: new RegExp("\"", "g"), val: """ } | ||
}, | ||
entities: [ | ||
{ regex: new RegExp("&", "g"), val: "&" },//it must be on top | ||
{ regex: new RegExp(">", "g"), val: ">" }, | ||
{ regex: new RegExp("<", "g"), val: "<" }, | ||
{ regex: new RegExp("\'", "g"), val: "'" }, | ||
{ regex: new RegExp("\"", "g"), val: """ } | ||
], | ||
processEntities: true, | ||
@@ -197,9 +199,16 @@ stopNodes: [] | ||
function buildTextValNode(val, key, attrStr, level) { | ||
let textValue = this.options.tagValueProcessor(key, val); | ||
textValue = this.replaceEntitiesValue(textValue); | ||
return ( | ||
this.indentate(level) + '<' + key + attrStr + '>' + | ||
textValue + | ||
'</' + key + this.tagEndChar ); | ||
const textValue = this.replaceEntitiesValue(val); | ||
if( textValue === '' && this.options.unpairedTags.indexOf(key) !== -1){ //unpaired | ||
if(this.options.suppressUnpairedNode){ | ||
return this.indentate(level) + '<' + key + this.tagEndChar; | ||
}else{ | ||
return this.indentate(level) + '<' + key + "/" + this.tagEndChar; | ||
} | ||
}else{ | ||
return ( | ||
this.indentate(level) + '<' + key + attrStr + '>' + | ||
textValue + | ||
'</' + key + this.tagEndChar ); | ||
} | ||
} | ||
@@ -209,4 +218,4 @@ | ||
if(textValue && textValue.length > 0 && this.options.processEntities){ | ||
for (const entityName in this.options.entities) { | ||
const entity = this.options.entities[entityName]; | ||
for (let i=0; i<this.options.entities.length; i++) { | ||
const entity = this.options.entities[i]; | ||
textValue = textValue.replace(entity.regex, entity.val); | ||
@@ -219,9 +228,13 @@ } | ||
function buildEmptyTextNode(val, key, attrStr, level) { | ||
if( val === '' && this.options.unpairedTags.indexOf(key) !== -1){ | ||
return this.indentate(level) + '<' + key + attrStr + this.tagEndChar; | ||
}else if (val !== '') { | ||
if( val === '' && this.options.unpairedTags.indexOf(key) !== -1){ //unpaired | ||
if(this.options.suppressUnpairedNode){ | ||
return this.indentate(level) + '<' + key + this.tagEndChar; | ||
}else{ | ||
return this.indentate(level) + '<' + key + "/" + this.tagEndChar; | ||
} | ||
}else if (val !== '') { //empty | ||
return this.buildTextValNode(val, key, attrStr, level); | ||
} else { | ||
if(key[0] === "?") return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar; | ||
else return this.indentate(level) + '<' + key + attrStr + '/' + this.tagEndChar; | ||
if(key[0] === "?") return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar; //PI tag | ||
else return this.indentate(level) + '<' + key + attrStr + '/' + this.tagEndChar; //normal | ||
} | ||
@@ -228,0 +241,0 @@ } |
@@ -51,3 +51,4 @@ const EOL = "\n"; | ||
if(options.unpairedTags.indexOf(tagName) !== -1){ | ||
xmlStr += tagStart + ">"; | ||
if(options.suppressUnpairedNode) xmlStr += tagStart + ">"; | ||
else xmlStr += tagStart + "/>"; | ||
}else if( (!tagValue || tagValue.length === 0) && options.suppressEmptyNode){ | ||
@@ -99,4 +100,4 @@ xmlStr += tagStart + "/>"; | ||
if(textValue && textValue.length > 0 && options.processEntities){ | ||
for (const entityName in options.entities) { | ||
const entity = options.entities[entityName]; | ||
for (let i=0; i< options.entities.length; i++) { | ||
const entity = options.entities[i]; | ||
textValue = textValue.replace(entity.regex, entity.val); | ||
@@ -103,0 +104,0 @@ } |
@@ -32,2 +32,4 @@ | ||
htmlEntities: false, | ||
ignoreDeclaration: false, | ||
ignorePiTags: false | ||
}; | ||
@@ -34,0 +36,0 @@ |
@@ -206,17 +206,25 @@ 'use strict'; | ||
} else if( xmlData[i+1] === '?') { | ||
let tagData = readTagExp(xmlData,i, false, "?>"); | ||
if(!tagData) throw new Error("Pi Tag is not closed."); | ||
textData = this.saveTextToParentTag(textData, currentNode, jPath); | ||
if( (this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags){ | ||
const childNode = new xmlNode(tagData.tagName); | ||
childNode.add(this.options.textNodeName, ""); | ||
if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){ | ||
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath); | ||
}else{ | ||
const childNode = new xmlNode(tagData.tagName); | ||
childNode.add(this.options.textNodeName, ""); | ||
if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){ | ||
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath); | ||
} | ||
currentNode.addChild(childNode); | ||
} | ||
currentNode.addChild(childNode); | ||
i = tagData.closeIndex + 1; | ||
} else if(xmlData.substr(i + 1, 3) === '!--') { | ||
const endIndex = findClosingIndex(xmlData, "-->", i, "Comment is not closed.") | ||
const endIndex = findClosingIndex(xmlData, "-->", i+4, "Comment is not closed.") | ||
if(this.options.commentPropName){ | ||
@@ -223,0 +231,0 @@ const comment = xmlData.substring(i + 4, endIndex - 2); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
93051
1778