fast-xml-parser
Advanced tools
Comparing version 4.0.0-beta.6 to 4.0.0-beta.7
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.0-beta.7 / 2021-12-09** | ||
* fix Validator bug when an attribute has no value but '=' only | ||
* XML Builder should suppress unpaired tags by default. | ||
* documents update for missing features | ||
* refactoring to use Object.assign | ||
* refactoring to remove repeated code | ||
** 4.0.0-beta.6 / 2021-12-05** | ||
@@ -4,0 +11,0 @@ * Support PI Tags processing |
{ | ||
"name": "fast-xml-parser", | ||
"version": "4.0.0-beta.6", | ||
"version": "4.0.0-beta.7", | ||
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries", | ||
@@ -5,0 +5,0 @@ "main": "./src/fxp.js", |
@@ -70,21 +70,4 @@ 'use strict'; | ||
const buildOptions = function(options, defaultOptions, props) { | ||
let newOptions = {}; | ||
if (!options) { | ||
return defaultOptions; //if there are not options | ||
} | ||
for (let i = 0; i < props.length; i++) { | ||
if (options[props[i]] !== undefined) { | ||
newOptions[props[i]] = options[props[i]]; | ||
} else { | ||
newOptions[props[i]] = defaultOptions[props[i]]; | ||
} | ||
} | ||
return newOptions; | ||
}; | ||
exports.buildOptions = buildOptions; | ||
exports.isName = isName; | ||
exports.getAllMatches = getAllMatches; | ||
exports.nameRegexp = nameRegexp; |
@@ -10,10 +10,5 @@ 'use strict'; | ||
const props = [ | ||
'allowBooleanAttributes', | ||
'unpairedTags' | ||
]; | ||
//const tagsPattern = new RegExp("<\\/?([\\w:\\-_\.]+)\\s*\/?>","g"); | ||
exports.validate = function (xmlData, options) { | ||
options = util.buildOptions(options, defaultOptions, props); | ||
options = Object.assign({}, defaultOptions, options); | ||
@@ -335,2 +330,4 @@ //xmlData = xmlData.replace(/(\r\n|\n|\r)/gm,"");//make it single line | ||
return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' has no space in starting.", getPositionFromMatch(matches[i])) | ||
} else if (matches[i][3] !== undefined && matches[i][4] === undefined) { | ||
return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' is without value.", getPositionFromMatch(matches[i])); | ||
} else if (matches[i][3] === undefined && !options.allowBooleanAttributes) { | ||
@@ -337,0 +334,0 @@ //independent attribute: ab |
'use strict'; | ||
//parse Empty Node as self closing node | ||
const buildOptions = require('../util').buildOptions; | ||
const buildFromOrderedJs = require('./orderedJs2Xml'); | ||
@@ -35,26 +34,4 @@ | ||
const props = [ | ||
'attributeNamePrefix', | ||
'attributesGroupName', | ||
'textNodeName', | ||
'ignoreAttributes', | ||
'cdataPropName', | ||
'format', | ||
'indentBy', | ||
'suppressEmptyNode', | ||
'suppressBooleanAttributes', | ||
'tagValueProcessor', | ||
'attributeValueProcessor', | ||
'arrayNodeName', //when array as root | ||
'preserveOrder', | ||
"commentPropName", | ||
"unpairedTags", | ||
"entities", | ||
"processEntities", | ||
"stopNodes", | ||
// 'rootNodeName', //when jsObject have multiple properties on root level | ||
]; | ||
function Builder(options) { | ||
this.options = buildOptions(options, defaultOptions, props); | ||
this.options = Object.assign({}, defaultOptions, options); | ||
if (this.options.ignoreAttributes || this.options.attributesGroupName) { | ||
@@ -61,0 +38,0 @@ this.isAttribute = function(/*a*/) { |
@@ -50,8 +50,6 @@ const {EOL} = require('os'); | ||
let tagValue = arrToStr(tagObj[tagName], options, newJPath, level + 1); | ||
if( (!tagValue || tagValue.length === 0) && options.suppressEmptyNode){ | ||
if(options.unpairedTags.indexOf(tagName) !== -1){ | ||
xmlStr += tagStart + ">"; | ||
}else{ | ||
xmlStr += tagStart + "/>"; | ||
} | ||
if(options.unpairedTags.indexOf(tagName) !== -1){ | ||
xmlStr += tagStart + ">"; | ||
}else if( (!tagValue || tagValue.length === 0) && options.suppressEmptyNode){ | ||
xmlStr += tagStart + "/>"; | ||
}else{ | ||
@@ -58,0 +56,0 @@ //TODO: node with only text value should not parse the text value in next line |
@@ -34,34 +34,7 @@ | ||
const props = [ | ||
'preserveOrder', | ||
'attributeNamePrefix', | ||
'attributesGroupName', | ||
'textNodeName', | ||
'ignoreAttributes', | ||
'removeNSPrefix', | ||
'allowBooleanAttributes', | ||
'parseTagValue', | ||
'parseAttributeValue', | ||
'trimValues', | ||
'cdataPropName', | ||
'tagValueProcessor', | ||
'attributeValueProcessor', | ||
'numberParseOptions', | ||
'stopNodes', | ||
'alwaysCreateTextNode', | ||
'isArray', | ||
'commentPropName', | ||
'unpairedTags', | ||
'processEntities', | ||
'htmlEntities' | ||
]; | ||
const util = require('../util'); | ||
const buildOptions = function(options) { | ||
return util.buildOptions(options, defaultOptions, props); | ||
return Object.assign({}, defaultOptions, options); | ||
}; | ||
exports.buildOptions = buildOptions; | ||
exports.defaultOptions = defaultOptions; | ||
exports.props = props; | ||
exports.defaultOptions = defaultOptions; |
@@ -52,2 +52,3 @@ 'use strict'; | ||
this.readStopNodeData = readStopNodeData; | ||
this.saveTextToParentTag = saveTextToParentTag; | ||
} | ||
@@ -212,32 +213,15 @@ | ||
} else if( xmlData[i+1] === '?') { | ||
let result = readTagExp(xmlData,i, false, "?>"); | ||
if(!result) throw new Error("Pi Tag is not closed."); | ||
let tagData = readTagExp(xmlData,i, false, "?>"); | ||
if(!tagData) throw new Error("Pi Tag is not closed."); | ||
textData = this.saveTextToParentTag(textData, currentNode, jPath); | ||
const childNode = new xmlNode(tagData.tagName); | ||
childNode.add(this.options.textNodeName, ""); | ||
let tagName= result.tagName; | ||
let tagExp = result.tagExp; | ||
let attrExpPresent = result.attrExpPresent; | ||
let closeIndex = result.closeIndex; | ||
if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){ | ||
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath); | ||
} | ||
currentNode.addChild(childNode); | ||
//TODO: remove repeated code | ||
if(textData){ //store previously collected data as textNode | ||
textData = this.parseTextData(textData | ||
, currentNode.tagname | ||
, jPath | ||
,false | ||
, currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false | ||
, Object.keys(currentNode.child).length === 0); | ||
if(textData !== undefined && textData !== "") currentNode.add(this.options.textNodeName, textData); | ||
textData = ""; | ||
} | ||
const childNode = new xmlNode(tagName); | ||
childNode.add(this.options.textNodeName, ""); | ||
if(tagName !== tagExp && attrExpPresent){ | ||
childNode[":@"] = this.buildAttributesMap(tagExp, jPath); | ||
} | ||
currentNode.addChild(childNode); | ||
i = closeIndex + 1; | ||
i = tagData.closeIndex + 1; | ||
} else if(xmlData.substr(i + 1, 3) === '!--') { | ||
@@ -248,14 +232,4 @@ const endIndex = findClosingIndex(xmlData, "-->", i, "Comment is not closed.") | ||
//TODO: remove repeated code | ||
if(textData){ //store previously collected data as textNode | ||
textData = this.parseTextData(textData | ||
, currentNode.tagname | ||
, jPath | ||
,false | ||
, currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false | ||
, Object.keys(currentNode.child).length === 0); | ||
if(textData !== undefined && textData !== "") currentNode.add(this.options.textNodeName, textData); | ||
textData = ""; | ||
} | ||
textData = this.saveTextToParentTag(textData, currentNode, jPath); | ||
currentNode.add(this.options.commentPropName, [ { [this.options.textNodeName] : comment } ]); | ||
@@ -272,14 +246,4 @@ } | ||
if(textData){ //store previously collected data as textNode | ||
textData = this.parseTextData(textData | ||
, currentNode.tagname | ||
, jPath | ||
,false | ||
, currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false | ||
, Object.keys(currentNode.child).length === 0); | ||
textData = this.saveTextToParentTag(textData, currentNode, jPath); | ||
if(textData !== undefined && textData !== "") currentNode.add(this.options.textNodeName, textData); | ||
textData = ""; | ||
} | ||
//cdata should be set even if it is 0 length string | ||
@@ -412,2 +376,18 @@ if(this.options.cdataPropName){ | ||
} | ||
function saveTextToParentTag(textData, currentNode, jPath) { | ||
if (textData) { //store previously collected data as textNode | ||
textData = this.parseTextData(textData, | ||
currentNode.tagname, | ||
jPath, | ||
false, | ||
currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false, | ||
Object.keys(currentNode.child).length === 0); | ||
if (textData !== undefined && textData !== "") | ||
currentNode.add(this.options.textNodeName, textData); | ||
textData = ""; | ||
} | ||
return textData; | ||
} | ||
//TODO: use jPath to simplify the logic | ||
@@ -414,0 +394,0 @@ /** |
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
90953
1775