Ajout du choix des utilisateurs sur un événement. Ajout de fichiers dans un événement. (dropzone cassée)
This commit is contained in:
16
em2rp/node_modules/fast-xml-parser/src/v5/CharsSymbol.js
generated
vendored
Normal file
16
em2rp/node_modules/fast-xml-parser/src/v5/CharsSymbol.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
modules.export = {
|
||||
"<" : "<", //tag start
|
||||
">" : ">", //tag end
|
||||
"/" : "/", //close tag
|
||||
"!" : "!", //comment or docttype
|
||||
"!--" : "!--", //comment
|
||||
"-->" : "-->", //comment end
|
||||
"?" : "?", //pi
|
||||
"?>" : "?>", //pi end
|
||||
"?xml" : "?xml", //pi end
|
||||
"![" : "![", //cdata
|
||||
"]]>" : "]]>", //cdata end
|
||||
"[" : "[",
|
||||
"-" : "-",
|
||||
"D" : "D",
|
||||
}
|
107
em2rp/node_modules/fast-xml-parser/src/v5/EntitiesParser.js
generated
vendored
Normal file
107
em2rp/node_modules/fast-xml-parser/src/v5/EntitiesParser.js
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"};
|
||||
const htmlEntities = {
|
||||
"space": { regex: /&(nbsp|#160);/g, val: " " },
|
||||
// "lt" : { regex: /&(lt|#60);/g, val: "<" },
|
||||
// "gt" : { regex: /&(gt|#62);/g, val: ">" },
|
||||
// "amp" : { regex: /&(amp|#38);/g, val: "&" },
|
||||
// "quot" : { regex: /&(quot|#34);/g, val: "\"" },
|
||||
// "apos" : { regex: /&(apos|#39);/g, val: "'" },
|
||||
"cent" : { regex: /&(cent|#162);/g, val: "¢" },
|
||||
"pound" : { regex: /&(pound|#163);/g, val: "£" },
|
||||
"yen" : { regex: /&(yen|#165);/g, val: "¥" },
|
||||
"euro" : { regex: /&(euro|#8364);/g, val: "€" },
|
||||
"copyright" : { regex: /&(copy|#169);/g, val: "©" },
|
||||
"reg" : { regex: /&(reg|#174);/g, val: "®" },
|
||||
"inr" : { regex: /&(inr|#8377);/g, val: "₹" },
|
||||
"num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) },
|
||||
"num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) },
|
||||
};
|
||||
|
||||
class EntitiesParser{
|
||||
constructor(replaceHtmlEntities) {
|
||||
this.replaceHtmlEntities = replaceHtmlEntities;
|
||||
this.docTypeEntities = {};
|
||||
this.lastEntities = {
|
||||
"apos" : { regex: /&(apos|#39|#x27);/g, val : "'"},
|
||||
"gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"},
|
||||
"lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"},
|
||||
"quot" : { regex: /&(quot|#34|#x22);/g, val : "\""},
|
||||
};
|
||||
}
|
||||
|
||||
addExternalEntities(externalEntities){
|
||||
const entKeys = Object.keys(externalEntities);
|
||||
for (let i = 0; i < entKeys.length; i++) {
|
||||
const ent = entKeys[i];
|
||||
this.addExternalEntity(ent,externalEntities[ent])
|
||||
}
|
||||
}
|
||||
addExternalEntity(key,val){
|
||||
validateEntityName(key);
|
||||
if(val.indexOf("&") !== -1) {
|
||||
reportWarning(`Entity ${key} is not added as '&' is found in value;`)
|
||||
return;
|
||||
}else{
|
||||
this.lastEntities[ent] = {
|
||||
regex: new RegExp("&"+key+";","g"),
|
||||
val : val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addDocTypeEntities(entities){
|
||||
const entKeys = Object.keys(entities);
|
||||
for (let i = 0; i < entKeys.length; i++) {
|
||||
const ent = entKeys[i];
|
||||
this.docTypeEntities[ent] = {
|
||||
regex: new RegExp("&"+ent+";","g"),
|
||||
val : entities[ent]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parse(val){
|
||||
return this.replaceEntitiesValue(val)
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Replace DOCTYPE entities
|
||||
* 2. Replace external entities
|
||||
* 3. Replace HTML entities if asked
|
||||
* @param {string} val
|
||||
*/
|
||||
replaceEntitiesValue(val){
|
||||
if(typeof val === "string" && val.length > 0){
|
||||
for(let entityName in this.docTypeEntities){
|
||||
const entity = this.docTypeEntities[entityName];
|
||||
val = val.replace( entity.regx, entity.val);
|
||||
}
|
||||
for(let entityName in this.lastEntities){
|
||||
const entity = this.lastEntities[entityName];
|
||||
val = val.replace( entity.regex, entity.val);
|
||||
}
|
||||
if(this.replaceHtmlEntities){
|
||||
for(let entityName in htmlEntities){
|
||||
const entity = htmlEntities[entityName];
|
||||
val = val.replace( entity.regex, entity.val);
|
||||
}
|
||||
}
|
||||
val = val.replace( ampEntity.regex, ampEntity.val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
//an entity name should not contains special characters that may be used in regex
|
||||
//Eg !?\\\/[]$%{}^&*()<>
|
||||
const specialChar = "!?\\\/[]$%{}^&*()<>|+";
|
||||
|
||||
function validateEntityName(name){
|
||||
for (let i = 0; i < specialChar.length; i++) {
|
||||
const ch = specialChar[i];
|
||||
if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
module.exports = EntitiesParser;
|
64
em2rp/node_modules/fast-xml-parser/src/v5/OptionsBuilder.js
generated
vendored
Normal file
64
em2rp/node_modules/fast-xml-parser/src/v5/OptionsBuilder.js
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
const JsObjOutputBuilder = require("./OutputBuilders/JsObjBuilder");
|
||||
|
||||
const defaultOptions = {
|
||||
preserveOrder: false,
|
||||
removeNSPrefix: false, // remove NS from tag name or attribute name if true
|
||||
//ignoreRootElement : false,
|
||||
stopNodes: [], //nested tags will not be parsed even for errors
|
||||
// isArray: () => false, //User will set it
|
||||
htmlEntities: false,
|
||||
// skipEmptyListItem: false
|
||||
tags:{
|
||||
unpaired: [],
|
||||
nameFor:{
|
||||
cdata: false,
|
||||
comment: false,
|
||||
text: '#text'
|
||||
},
|
||||
separateTextProperty: false,
|
||||
},
|
||||
attributes:{
|
||||
ignore: false,
|
||||
booleanType: true,
|
||||
entities: true,
|
||||
},
|
||||
|
||||
// select: ["img[src]"],
|
||||
// stop: ["anim", "[ads]"]
|
||||
only: [], // rest tags will be skipped. It will result in flat array
|
||||
hierarchy: false, //will be used when a particular tag is set to be parsed.
|
||||
skip: [], // will be skipped from parse result. on('skip') will be triggered
|
||||
|
||||
select: [], // on('select', tag => tag ) will be called if match
|
||||
stop: [], //given tagPath will not be parsed. innerXML will be set as string value
|
||||
OutputBuilder: new JsObjOutputBuilder(),
|
||||
};
|
||||
|
||||
const buildOptions = function(options) {
|
||||
const finalOptions = { ... defaultOptions};
|
||||
copyProperties(finalOptions,options)
|
||||
return finalOptions;
|
||||
};
|
||||
|
||||
function copyProperties(target, source) {
|
||||
for (let key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
if (key === 'OutputBuilder') {
|
||||
target[key] = source[key];
|
||||
}else if (typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
||||
// Recursively copy nested properties
|
||||
if (typeof target[key] === 'undefined') {
|
||||
target[key] = {};
|
||||
}
|
||||
copyProperties(target[key], source[key]);
|
||||
} else {
|
||||
// Copy non-nested properties
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.buildOptions = buildOptions;
|
||||
exports.defaultOptions = defaultOptions;
|
71
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/BaseOutputBuilder.js
generated
vendored
Normal file
71
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/BaseOutputBuilder.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
class BaseOutputBuilder{
|
||||
constructor(){
|
||||
// this.attributes = {};
|
||||
}
|
||||
|
||||
addAttribute(name, value){
|
||||
if(this.options.onAttribute){
|
||||
//TODO: better to pass tag path
|
||||
const v = this.options.onAttribute(name, value, this.tagName);
|
||||
if(v) this.attributes[v.name] = v.value;
|
||||
}else{
|
||||
name = this.options.attributes.prefix + name + this.options.attributes.suffix;
|
||||
this.attributes[name] = this.parseValue(value, this.options.attributes.valueParsers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parse value by chain of parsers
|
||||
* @param {string} val
|
||||
* @returns {any} parsed value if matching parser found
|
||||
*/
|
||||
parseValue = function(val, valParsers){
|
||||
for (let i = 0; i < valParsers.length; i++) {
|
||||
let valParser = valParsers[i];
|
||||
if(typeof valParser === "string"){
|
||||
valParser = this.registeredParsers[valParser];
|
||||
}
|
||||
if(valParser){
|
||||
val = valParser.parse(val);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* To add a nested empty tag.
|
||||
* @param {string} key
|
||||
* @param {any} val
|
||||
*/
|
||||
_addChild(key, val){}
|
||||
|
||||
/**
|
||||
* skip the comment if property is not set
|
||||
*/
|
||||
addComment(text){
|
||||
if(this.options.nameFor.comment)
|
||||
this._addChild(this.options.nameFor.comment, text);
|
||||
}
|
||||
|
||||
//store CDATA separately if property is set
|
||||
//otherwise add to tag's value
|
||||
addCdata(text){
|
||||
if (this.options.nameFor.cdata) {
|
||||
this._addChild(this.options.nameFor.cdata, text);
|
||||
} else {
|
||||
this.addRawValue(text || "");
|
||||
}
|
||||
}
|
||||
|
||||
addRawValue = text => this.addValue(text);
|
||||
|
||||
addDeclaration(){
|
||||
if(!this.options.declaration){
|
||||
}else{
|
||||
this.addPi("?xml");
|
||||
}
|
||||
this.attributes = {}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BaseOutputBuilder;
|
103
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsArrBuilder.js
generated
vendored
Normal file
103
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsArrBuilder.js
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
const {buildOptions,registerCommonValueParsers} = require("./ParserOptionsBuilder");
|
||||
|
||||
class OutputBuilder{
|
||||
constructor(options){
|
||||
this.options = buildOptions(options);
|
||||
this.registeredParsers = registerCommonValueParsers(this.options);
|
||||
}
|
||||
|
||||
registerValueParser(name,parserInstance){//existing name will override the parser without warning
|
||||
this.registeredParsers[name] = parserInstance;
|
||||
}
|
||||
|
||||
getInstance(parserOptions){
|
||||
return new JsArrBuilder(parserOptions, this.options, this.registeredParsers);
|
||||
}
|
||||
}
|
||||
|
||||
const rootName = '!js_arr';
|
||||
const BaseOutputBuilder = require("./BaseOutputBuilder");
|
||||
|
||||
class JsArrBuilder extends BaseOutputBuilder{
|
||||
|
||||
constructor(parserOptions, options,registeredParsers) {
|
||||
super();
|
||||
this.tagsStack = [];
|
||||
this.parserOptions = parserOptions;
|
||||
this.options = options;
|
||||
this.registeredParsers = registeredParsers;
|
||||
|
||||
this.root = new Node(rootName);
|
||||
this.currentNode = this.root;
|
||||
this.attributes = {};
|
||||
}
|
||||
|
||||
addTag(tag){
|
||||
//when a new tag is added, it should be added as child of current node
|
||||
//TODO: shift this check to the parser
|
||||
if(tag.name === "__proto__") tag.name = "#__proto__";
|
||||
|
||||
this.tagsStack.push(this.currentNode);
|
||||
this.currentNode = new Node(tag.name, this.attributes);
|
||||
this.attributes = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the node should be added by checking user's preference
|
||||
* @param {Node} node
|
||||
* @returns boolean: true if the node should not be added
|
||||
*/
|
||||
closeTag(){
|
||||
const node = this.currentNode;
|
||||
this.currentNode = this.tagsStack.pop(); //set parent node in scope
|
||||
if(this.options.onClose !== undefined){
|
||||
//TODO TagPathMatcher
|
||||
const resultTag = this.options.onClose(node,
|
||||
new TagPathMatcher(this.tagsStack,node));
|
||||
|
||||
if(resultTag) return;
|
||||
}
|
||||
this.currentNode.child.push(node); //to parent node
|
||||
}
|
||||
|
||||
//Called by parent class methods
|
||||
_addChild(key, val){
|
||||
// if(key === "__proto__") tagName = "#__proto__";
|
||||
this.currentNode.child.push( {[key]: val });
|
||||
// this.currentNode.leafType = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add text value child node
|
||||
* @param {string} text
|
||||
*/
|
||||
addValue(text){
|
||||
this.currentNode.child.push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) });
|
||||
}
|
||||
|
||||
addPi(name){
|
||||
//TODO: set pi flag
|
||||
if(!this.options.ignorePiTags){
|
||||
const node = new Node(name, this.attributes);
|
||||
this.currentNode[":@"] = this.attributes;
|
||||
this.currentNode.child.push(node);
|
||||
}
|
||||
this.attributes = {};
|
||||
}
|
||||
getOutput(){
|
||||
return this.root.child[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Node{
|
||||
constructor(tagname, attributes){
|
||||
this.tagname = tagname;
|
||||
this.child = []; //nested tags, text, cdata, comments
|
||||
if(attributes && Object.keys(attributes).length > 0)
|
||||
this[":@"] = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OutputBuilder;
|
102
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsMinArrBuilder.js
generated
vendored
Normal file
102
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsMinArrBuilder.js
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
const {buildOptions,registerCommonValueParsers} = require("./ParserOptionsBuilder");
|
||||
|
||||
class OutputBuilder{
|
||||
constructor(options){
|
||||
this.options = buildOptions(options);
|
||||
this.registeredParsers = registerCommonValueParsers(this.options);
|
||||
}
|
||||
|
||||
registerValueParser(name,parserInstance){//existing name will override the parser without warning
|
||||
this.registeredParsers[name] = parserInstance;
|
||||
}
|
||||
|
||||
getInstance(parserOptions){
|
||||
return new JsMinArrBuilder(parserOptions, this.options, this.registeredParsers);
|
||||
}
|
||||
}
|
||||
|
||||
const BaseOutputBuilder = require("./BaseOutputBuilder");
|
||||
const rootName = '^';
|
||||
|
||||
class JsMinArrBuilder extends BaseOutputBuilder{
|
||||
|
||||
constructor(parserOptions, options,registeredParsers) {
|
||||
super();
|
||||
this.tagsStack = [];
|
||||
this.parserOptions = parserOptions;
|
||||
this.options = options;
|
||||
this.registeredParsers = registeredParsers;
|
||||
|
||||
this.root = {[rootName]: []};
|
||||
this.currentNode = this.root;
|
||||
this.currentNodeTagName = rootName;
|
||||
this.attributes = {};
|
||||
}
|
||||
|
||||
addTag(tag){
|
||||
//when a new tag is added, it should be added as child of current node
|
||||
//TODO: shift this check to the parser
|
||||
if(tag.name === "__proto__") tag.name = "#__proto__";
|
||||
|
||||
this.tagsStack.push([this.currentNodeTagName,this.currentNode]); //this.currentNode is parent node here
|
||||
this.currentNodeTagName = tag.name;
|
||||
this.currentNode = { [tag.name]:[]}
|
||||
if(Object.keys(this.attributes).length > 0){
|
||||
this.currentNode[":@"] = this.attributes;
|
||||
this.attributes = {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the node should be added by checking user's preference
|
||||
* @param {Node} node
|
||||
* @returns boolean: true if the node should not be added
|
||||
*/
|
||||
closeTag(){
|
||||
const node = this.currentNode;
|
||||
const nodeName = this.currentNodeTagName;
|
||||
const arr = this.tagsStack.pop(); //set parent node in scope
|
||||
this.currentNodeTagName = arr[0];
|
||||
this.currentNode = arr[1];
|
||||
|
||||
if(this.options.onClose !== undefined){
|
||||
//TODO TagPathMatcher
|
||||
const resultTag = this.options.onClose(node,
|
||||
new TagPathMatcher(this.tagsStack,node));
|
||||
|
||||
if(resultTag) return;
|
||||
}
|
||||
this.currentNode[this.currentNodeTagName].push(node); //to parent node
|
||||
}
|
||||
|
||||
//Called by parent class methods
|
||||
_addChild(key, val){
|
||||
// if(key === "__proto__") tagName = "#__proto__";
|
||||
this.currentNode.push( {[key]: val });
|
||||
// this.currentNode.leafType = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add text value child node
|
||||
* @param {string} text
|
||||
*/
|
||||
addValue(text){
|
||||
this.currentNode[this.currentNodeTagName].push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) });
|
||||
}
|
||||
|
||||
addPi(name){
|
||||
if(!this.options.ignorePiTags){
|
||||
const node = { [name]:[]}
|
||||
if(this.attributes){
|
||||
node[":@"] = this.attributes;
|
||||
}
|
||||
this.currentNode.push(node);
|
||||
}
|
||||
this.attributes = {};
|
||||
}
|
||||
getOutput(){
|
||||
return this.root[rootName];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OutputBuilder;
|
156
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsObjBuilder.js
generated
vendored
Normal file
156
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsObjBuilder.js
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
|
||||
|
||||
const {buildOptions,registerCommonValueParsers} = require("./ParserOptionsBuilder");
|
||||
|
||||
class OutputBuilder{
|
||||
constructor(builderOptions){
|
||||
this.options = buildOptions(builderOptions);
|
||||
this.registeredParsers = registerCommonValueParsers(this.options);
|
||||
}
|
||||
|
||||
registerValueParser(name,parserInstance){//existing name will override the parser without warning
|
||||
this.registeredParsers[name] = parserInstance;
|
||||
}
|
||||
|
||||
getInstance(parserOptions){
|
||||
return new JsObjBuilder(parserOptions, this.options, this.registeredParsers);
|
||||
}
|
||||
}
|
||||
|
||||
const BaseOutputBuilder = require("./BaseOutputBuilder");
|
||||
const rootName = '^';
|
||||
|
||||
class JsObjBuilder extends BaseOutputBuilder{
|
||||
|
||||
constructor(parserOptions, builderOptions,registeredParsers) {
|
||||
super();
|
||||
//hold the raw detail of a tag and sequence with reference to the output
|
||||
this.tagsStack = [];
|
||||
this.parserOptions = parserOptions;
|
||||
this.options = builderOptions;
|
||||
this.registeredParsers = registeredParsers;
|
||||
|
||||
this.root = {};
|
||||
this.parent = this.root;
|
||||
this.tagName = rootName;
|
||||
this.value = {};
|
||||
this.textValue = "";
|
||||
this.attributes = {};
|
||||
}
|
||||
|
||||
addTag(tag){
|
||||
|
||||
let value = "";
|
||||
if( !isEmpty(this.attributes)){
|
||||
value = {};
|
||||
if(this.options.attributes.groupBy){
|
||||
value[this.options.attributes.groupBy] = this.attributes;
|
||||
}else{
|
||||
value = this.attributes;
|
||||
}
|
||||
}
|
||||
|
||||
this.tagsStack.push([this.tagName, this.textValue, this.value]); //parent tag, parent text value, parent tag value (jsobj)
|
||||
this.tagName = tag.name;
|
||||
this.value = value;
|
||||
this.textValue = "";
|
||||
this.attributes = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the node should be added by checking user's preference
|
||||
* @param {Node} node
|
||||
* @returns boolean: true if the node should not be added
|
||||
*/
|
||||
closeTag(){
|
||||
const tagName = this.tagName;
|
||||
let value = this.value;
|
||||
let textValue = this.textValue;
|
||||
|
||||
//update tag text value
|
||||
if(typeof value !== "object" && !Array.isArray(value)){
|
||||
value = this.parseValue(textValue.trim(), this.options.tags.valueParsers);
|
||||
}else if(textValue.length > 0){
|
||||
value[this.options.nameFor.text] = this.parseValue(textValue.trim(), this.options.tags.valueParsers);
|
||||
}
|
||||
|
||||
|
||||
let resultTag= {
|
||||
tagName: tagName,
|
||||
value: value
|
||||
};
|
||||
|
||||
if(this.options.onTagClose !== undefined){
|
||||
//TODO TagPathMatcher
|
||||
resultTag = this.options.onClose(tagName, value, this.textValue, new TagPathMatcher(this.tagsStack,node));
|
||||
|
||||
if(!resultTag) return;
|
||||
}
|
||||
|
||||
//set parent node in scope
|
||||
let arr = this.tagsStack.pop();
|
||||
let parentTag = arr[2];
|
||||
parentTag=this._addChildTo(resultTag.tagName, resultTag.value, parentTag);
|
||||
|
||||
this.tagName = arr[0];
|
||||
this.textValue = arr[1];
|
||||
this.value = parentTag;
|
||||
}
|
||||
|
||||
_addChild(key, val){
|
||||
if(typeof this.value === "string"){
|
||||
this.value = { [this.options.nameFor.text] : this.value };
|
||||
}
|
||||
|
||||
this._addChildTo(key, val, this.value);
|
||||
// this.currentNode.leafType = false;
|
||||
this.attributes = {};
|
||||
}
|
||||
|
||||
_addChildTo(key, val, node){
|
||||
if(typeof node === 'string') node = {};
|
||||
if(!node[key]){
|
||||
node[key] = val;
|
||||
}else{ //Repeated
|
||||
if(!Array.isArray(node[key])){ //but not stored as array
|
||||
node[key] = [node[key]];
|
||||
}
|
||||
node[key].push(val);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add text value child node
|
||||
* @param {string} text
|
||||
*/
|
||||
addValue(text){
|
||||
//TODO: use bytes join
|
||||
if(this.textValue.length > 0) this.textValue += " " + text;
|
||||
else this.textValue = text;
|
||||
}
|
||||
|
||||
addPi(name){
|
||||
let value = "";
|
||||
if( !isEmpty(this.attributes)){
|
||||
value = {};
|
||||
if(this.options.attributes.groupBy){
|
||||
value[this.options.attributes.groupBy] = this.attributes;
|
||||
}else{
|
||||
value = this.attributes;
|
||||
}
|
||||
}
|
||||
this._addChild(name, value);
|
||||
|
||||
}
|
||||
getOutput(){
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
function isEmpty(obj) {
|
||||
return Object.keys(obj).length === 0;
|
||||
}
|
||||
|
||||
module.exports = OutputBuilder;
|
99
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/ParserOptionsBuilder.js
generated
vendored
Normal file
99
em2rp/node_modules/fast-xml-parser/src/v5/OutputBuilders/ParserOptionsBuilder.js
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
const trimParser = require("../valueParsers/trim")
|
||||
const booleanParser = require("../valueParsers/booleanParser")
|
||||
const currencyParser = require("../valueParsers/currency")
|
||||
const numberParser = require("../valueParsers/number")
|
||||
|
||||
const defaultOptions={
|
||||
nameFor:{
|
||||
text: "#text",
|
||||
comment: "",
|
||||
cdata: "",
|
||||
},
|
||||
// onTagClose: () => {},
|
||||
// onAttribute: () => {},
|
||||
piTag: false,
|
||||
declaration: false, //"?xml"
|
||||
tags: {
|
||||
valueParsers: [
|
||||
// "trim",
|
||||
// "boolean",
|
||||
// "number",
|
||||
// "currency",
|
||||
// "date",
|
||||
]
|
||||
},
|
||||
attributes:{
|
||||
prefix: "@_",
|
||||
suffix: "",
|
||||
groupBy: "",
|
||||
|
||||
valueParsers: [
|
||||
// "trim",
|
||||
// "boolean",
|
||||
// "number",
|
||||
// "currency",
|
||||
// "date",
|
||||
]
|
||||
},
|
||||
dataType:{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
const withJoin = ["trim","join", /*"entities",*/"number","boolean","currency"/*, "date"*/]
|
||||
const withoutJoin = ["trim", /*"entities",*/"number","boolean","currency"/*, "date"*/]
|
||||
|
||||
function buildOptions(options){
|
||||
//clone
|
||||
const finalOptions = { ... defaultOptions};
|
||||
|
||||
//add config missed in cloning
|
||||
finalOptions.tags.valueParsers.push(...withJoin)
|
||||
if(!this.preserveOrder)
|
||||
finalOptions.tags.valueParsers.push(...withoutJoin);
|
||||
|
||||
//add config missed in cloning
|
||||
finalOptions.attributes.valueParsers.push(...withJoin)
|
||||
|
||||
//override configuration
|
||||
copyProperties(finalOptions,options);
|
||||
return finalOptions;
|
||||
}
|
||||
|
||||
function copyProperties(target, source) {
|
||||
for (let key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
if (typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
||||
// Recursively copy nested properties
|
||||
if (typeof target[key] === 'undefined') {
|
||||
target[key] = {};
|
||||
}
|
||||
copyProperties(target[key], source[key]);
|
||||
} else {
|
||||
// Copy non-nested properties
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerCommonValueParsers(options){
|
||||
return {
|
||||
"trim": new trimParser(),
|
||||
// "join": this.entityParser.parse,
|
||||
"boolean": new booleanParser(),
|
||||
"number": new numberParser({
|
||||
hex: true,
|
||||
leadingZeros: true,
|
||||
eNotation: true
|
||||
}),
|
||||
"currency": new currencyParser(),
|
||||
// "date": this.entityParser.parse,
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildOptions : buildOptions,
|
||||
registerCommonValueParsers: registerCommonValueParsers
|
||||
}
|
0
em2rp/node_modules/fast-xml-parser/src/v5/Report.js
generated
vendored
Normal file
0
em2rp/node_modules/fast-xml-parser/src/v5/Report.js
generated
vendored
Normal file
81
em2rp/node_modules/fast-xml-parser/src/v5/TagPath.js
generated
vendored
Normal file
81
em2rp/node_modules/fast-xml-parser/src/v5/TagPath.js
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
class TagPath{
|
||||
constructor(pathStr){
|
||||
let text = "";
|
||||
let tName = "";
|
||||
let pos;
|
||||
let aName = "";
|
||||
let aVal = "";
|
||||
this.stack = []
|
||||
|
||||
for (let i = 0; i < pathStr.length; i++) {
|
||||
let ch = pathStr[i];
|
||||
if(ch === " ") {
|
||||
if(text.length === 0) continue;
|
||||
tName = text; text = "";
|
||||
}else if(ch === "["){
|
||||
if(tName.length === 0){
|
||||
tName = text; text = "";
|
||||
}
|
||||
i++;
|
||||
for (; i < pathStr.length; i++) {
|
||||
ch = pathStr[i];
|
||||
if(ch=== "=") continue;
|
||||
else if(ch=== "]") {aName = text.trim(); text=""; break; i--;}
|
||||
else if(ch === "'" || ch === '"'){
|
||||
let attrEnd = pathStr.indexOf(ch,i+1);
|
||||
aVal = pathStr.substring(i+1, attrEnd);
|
||||
i = attrEnd;
|
||||
}else{
|
||||
text +=ch;
|
||||
}
|
||||
}
|
||||
}else if(ch !== " " && text.length === 0 && tName.length > 0){//reading tagName
|
||||
//save previous tag
|
||||
this.stack.push(new TagPathNode(tName,pos,aName,aVal));
|
||||
text = ch; tName = ""; aName = ""; aVal = "";
|
||||
}else{
|
||||
text+=ch;
|
||||
}
|
||||
}
|
||||
|
||||
//last tag in the path
|
||||
if(tName.length >0 || text.length>0){
|
||||
this.stack.push(new TagPathNode(text||tName,pos,aName,aVal));
|
||||
}
|
||||
}
|
||||
|
||||
match(tagStack,node){
|
||||
if(this.stack[0].name !== "*"){
|
||||
if(this.stack.length !== tagStack.length +1) return false;
|
||||
|
||||
//loop through tagPath and tagStack and match
|
||||
for (let i = 0; i < this.tagStack.length; i++) {
|
||||
if(!this.stack[i].match(tagStack[i])) return false;
|
||||
}
|
||||
}
|
||||
if(!this.stack[this.stack.length - 1].match(node)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TagPathNode{
|
||||
constructor(name,position,attrName,attrVal){
|
||||
this.name = name;
|
||||
this.position = position;
|
||||
this.attrName = attrName,
|
||||
this.attrVal = attrVal;
|
||||
}
|
||||
|
||||
match(node){
|
||||
let matching = true;
|
||||
matching = node.name === this.name;
|
||||
if(this.position) matching = node.position === this.position;
|
||||
if(this.attrName) matching = node.attrs[this.attrName !== undefined];
|
||||
if(this.attrVal) matching = node.attrs[this.attrName !== this.attrVal];
|
||||
return matching;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log((new TagPath("* b[b]")).stack);
|
||||
// console.log((new TagPath("a[a] b[b] c")).stack);
|
||||
// console.log((new TagPath(" b [ b= 'cf sdadwa' ] a ")).stack);
|
15
em2rp/node_modules/fast-xml-parser/src/v5/TagPathMatcher.js
generated
vendored
Normal file
15
em2rp/node_modules/fast-xml-parser/src/v5/TagPathMatcher.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
const TagPath = require("./TagPath");
|
||||
|
||||
class TagPathMatcher{
|
||||
constructor(stack,node){
|
||||
this.stack = stack;
|
||||
this.node= node;
|
||||
}
|
||||
|
||||
match(path){
|
||||
const tagPath = new TagPath(path);
|
||||
return tagPath.match(this.stack, this.node);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TagPathMatcher;
|
85
em2rp/node_modules/fast-xml-parser/src/v5/XMLParser.js
generated
vendored
Normal file
85
em2rp/node_modules/fast-xml-parser/src/v5/XMLParser.js
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
const { buildOptions} = require("./OptionsBuilder");
|
||||
const Xml2JsParser = require("./Xml2JsParser");
|
||||
|
||||
class XMLParser{
|
||||
|
||||
constructor(options){
|
||||
this.externalEntities = {};
|
||||
this.options = buildOptions(options);
|
||||
// console.log(this.options)
|
||||
}
|
||||
/**
|
||||
* Parse XML data string to JS object
|
||||
* @param {string|Buffer} xmlData
|
||||
* @param {boolean|Object} validationOption
|
||||
*/
|
||||
parse(xmlData){
|
||||
if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){
|
||||
return this.parse(xmlData);
|
||||
}else if( xmlData.toString){
|
||||
xmlData = xmlData.toString();
|
||||
}else{
|
||||
throw new Error("XML data is accepted in String or Bytes[] form.")
|
||||
}
|
||||
// if( validationOption){
|
||||
// if(validationOption === true) validationOption = {}; //validate with default options
|
||||
|
||||
// const result = validator.validate(xmlData, validationOption);
|
||||
// if (result !== true) {
|
||||
// throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` )
|
||||
// }
|
||||
// }
|
||||
const parser = new Xml2JsParser(this.options);
|
||||
parser.entityParser.addExternalEntities(this.externalEntities);
|
||||
return parser.parse(xmlData);
|
||||
}
|
||||
/**
|
||||
* Parse XML data buffer to JS object
|
||||
* @param {string|Buffer} xmlData
|
||||
* @param {boolean|Object} validationOption
|
||||
*/
|
||||
parseBytesArr(xmlData){
|
||||
if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){
|
||||
}else{
|
||||
throw new Error("XML data is accepted in Bytes[] form.")
|
||||
}
|
||||
const parser = new Xml2JsParser(this.options);
|
||||
parser.entityParser.addExternalEntities(this.externalEntities);
|
||||
return parser.parseBytesArr(xmlData);
|
||||
}
|
||||
/**
|
||||
* Parse XML data stream to JS object
|
||||
* @param {fs.ReadableStream} xmlDataStream
|
||||
*/
|
||||
parseStream(xmlDataStream){
|
||||
if(!isStream(xmlDataStream)) throw new Error("FXP: Invalid stream input");
|
||||
|
||||
const orderedObjParser = new Xml2JsParser(this.options);
|
||||
orderedObjParser.entityParser.addExternalEntities(this.externalEntities);
|
||||
return orderedObjParser.parseStream(xmlDataStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Entity which is not by default supported by this library
|
||||
* @param {string} key
|
||||
* @param {string} value
|
||||
*/
|
||||
addEntity(key, value){
|
||||
if(value.indexOf("&") !== -1){
|
||||
throw new Error("Entity value can't have '&'")
|
||||
}else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){
|
||||
throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'")
|
||||
}else if(value === "&"){
|
||||
throw new Error("An entity with value '&' is not permitted");
|
||||
}else{
|
||||
this.externalEntities[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isStream(stream){
|
||||
if(stream && typeof stream.read === "function" && typeof stream.on === "function" && typeof stream.readableEnded === "boolean") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = XMLParser;
|
237
em2rp/node_modules/fast-xml-parser/src/v5/Xml2JsParser.js
generated
vendored
Normal file
237
em2rp/node_modules/fast-xml-parser/src/v5/Xml2JsParser.js
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
const StringSource = require("./inputSource/StringSource");
|
||||
const BufferSource = require("./inputSource/BufferSource");
|
||||
const {readTagExp,readClosingTagName} = require("./XmlPartReader");
|
||||
const {readComment, readCdata,readDocType,readPiTag} = require("./XmlSpecialTagsReader");
|
||||
const TagPath = require("./TagPath");
|
||||
const TagPathMatcher = require("./TagPathMatcher");
|
||||
const EntitiesParser = require('./EntitiesParser');
|
||||
|
||||
//To hold the data of current tag
|
||||
//This is usually used to compare jpath expression against current tag
|
||||
class TagDetail{
|
||||
constructor(name){
|
||||
this.name = name;
|
||||
this.position = 0;
|
||||
// this.attributes = {};
|
||||
}
|
||||
}
|
||||
|
||||
class Xml2JsParser {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
|
||||
this.currentTagDetail = null;
|
||||
this.tagTextData = "";
|
||||
this.tagsStack = [];
|
||||
this.entityParser = new EntitiesParser(options.htmlEntities);
|
||||
this.stopNodes = [];
|
||||
for (let i = 0; i < this.options.stopNodes.length; i++) {
|
||||
this.stopNodes.push(new TagPath(this.options.stopNodes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
parse(strData) {
|
||||
this.source = new StringSource(strData);
|
||||
this.parseXml();
|
||||
return this.outputBuilder.getOutput();
|
||||
}
|
||||
parseBytesArr(data) {
|
||||
this.source = new BufferSource(data );
|
||||
this.parseXml();
|
||||
return this.outputBuilder.getOutput();
|
||||
}
|
||||
|
||||
parseXml() {
|
||||
//TODO: Separate TagValueParser as separate class. So no scope issue in node builder class
|
||||
|
||||
//OutputBuilder should be set in XML Parser
|
||||
this.outputBuilder = this.options.OutputBuilder.getInstance(this.options);
|
||||
this.root = { root: true};
|
||||
this.currentTagDetail = this.root;
|
||||
|
||||
while(this.source.canRead()){
|
||||
let ch = this.source.readCh();
|
||||
if (ch === "") break;
|
||||
|
||||
if(ch === "<"){//tagStart
|
||||
let nextChar = this.source.readChAt(0);
|
||||
if (nextChar === "" ) throw new Error("Unexpected end of source");
|
||||
|
||||
|
||||
if(nextChar === "!" || nextChar === "?"){
|
||||
this.source.updateBufferBoundary();
|
||||
//previously collected text should be added to current node
|
||||
this.addTextNode();
|
||||
|
||||
this.readSpecialTag(nextChar);// Read DOCTYPE, comment, CDATA, PI tag
|
||||
}else if(nextChar === "/"){
|
||||
this.source.updateBufferBoundary();
|
||||
this.readClosingTag();
|
||||
// console.log(this.source.buffer.length, this.source.readable);
|
||||
// console.log(this.tagsStack.length);
|
||||
}else{//opening tag
|
||||
this.readOpeningTag();
|
||||
}
|
||||
}else{
|
||||
this.tagTextData += ch;
|
||||
}
|
||||
}//End While loop
|
||||
if(this.tagsStack.length > 0 || ( this.tagTextData !== "undefined" && this.tagTextData.trimEnd().length > 0) ) throw new Error("Unexpected data in the end of document");
|
||||
}
|
||||
|
||||
/**
|
||||
* read closing paired tag. Set parent tag in scope.
|
||||
* skip a node on user's choice
|
||||
*/
|
||||
readClosingTag(){
|
||||
const tagName = this.processTagName(readClosingTagName(this.source));
|
||||
// console.log(tagName, this.tagsStack.length);
|
||||
this.validateClosingTag(tagName);
|
||||
// All the text data collected, belongs to current tag.
|
||||
if(!this.currentTagDetail.root) this.addTextNode();
|
||||
this.outputBuilder.closeTag();
|
||||
// Since the tag is closed now, parent tag comes in scope
|
||||
this.currentTagDetail = this.tagsStack.pop();
|
||||
}
|
||||
|
||||
validateClosingTag(tagName){
|
||||
// This can't be unpaired tag, or a stop tag.
|
||||
if(this.isUnpaired(tagName) || this.isStopNode(tagName)) throw new Error(`Unexpected closing tag '${tagName}'`);
|
||||
// This must match with last opening tag
|
||||
else if(tagName !== this.currentTagDetail.name)
|
||||
throw new Error(`Unexpected closing tag '${tagName}' expecting '${this.currentTagDetail.name}'`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Read paired, unpaired, self-closing, stop and special tags.
|
||||
* Create a new node
|
||||
* Push paired tag in stack.
|
||||
*/
|
||||
readOpeningTag(){
|
||||
//save previously collected text data to current node
|
||||
this.addTextNode();
|
||||
|
||||
//create new tag
|
||||
let tagExp = readTagExp(this, ">" );
|
||||
|
||||
// process and skip from tagsStack For unpaired tag, self closing tag, and stop node
|
||||
const tagDetail = new TagDetail(tagExp.tagName);
|
||||
if(this.isUnpaired(tagExp.tagName)) {
|
||||
//TODO: this will lead 2 extra stack operation
|
||||
this.outputBuilder.addTag(tagDetail);
|
||||
this.outputBuilder.closeTag();
|
||||
} else if(tagExp.selfClosing){
|
||||
this.outputBuilder.addTag(tagDetail);
|
||||
this.outputBuilder.closeTag();
|
||||
} else if(this.isStopNode(this.currentTagDetail)){
|
||||
// TODO: let's user set a stop node boundary detector for complex contents like script tag
|
||||
//TODO: pass tag name only to avoid string operations
|
||||
const content = source.readUptoCloseTag(`</${tagExp.tagName}`);
|
||||
this.outputBuilder.addTag(tagDetail);
|
||||
this.outputBuilder.addValue(content);
|
||||
this.outputBuilder.closeTag();
|
||||
}else{//paired tag
|
||||
//set new nested tag in scope.
|
||||
this.tagsStack.push(this.currentTagDetail);
|
||||
this.outputBuilder.addTag(tagDetail);
|
||||
this.currentTagDetail = tagDetail;
|
||||
}
|
||||
// console.log(tagExp.tagName,this.tagsStack.length);
|
||||
// this.options.onClose()
|
||||
|
||||
}
|
||||
|
||||
readSpecialTag(startCh){
|
||||
if(startCh == "!"){
|
||||
let nextChar = this.source.readCh();
|
||||
if (nextChar === null || nextChar === undefined) throw new Error("Unexpected ending of the source");
|
||||
|
||||
if(nextChar === "-"){//comment
|
||||
readComment(this);
|
||||
}else if(nextChar === "["){//CDATA
|
||||
readCdata(this);
|
||||
}else if(nextChar === "D"){//DOCTYPE
|
||||
readDocType(this);
|
||||
}
|
||||
}else if(startCh === "?"){
|
||||
readPiTag(this);
|
||||
}else{
|
||||
throw new Error(`Invalid tag '<${startCh}' at ${this.source.line}:${this.source.col}`)
|
||||
}
|
||||
}
|
||||
addTextNode = function() {
|
||||
// if(this.currentTagDetail){
|
||||
//save text as child node
|
||||
// if(this.currentTagDetail.tagname !== '!xml')
|
||||
if (this.tagTextData !== undefined && this.tagTextData !== "") { //store previously collected data as textNode
|
||||
if(this.tagTextData.trim().length > 0){
|
||||
//TODO: shift parsing to output builder
|
||||
|
||||
this.outputBuilder.addValue(this.replaceEntities(this.tagTextData));
|
||||
}
|
||||
this.tagTextData = "";
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
processAttrName(name){
|
||||
if(name === "__proto__") name = "#__proto__";
|
||||
name = resolveNameSpace(name, this.removeNSPrefix);
|
||||
return name;
|
||||
}
|
||||
|
||||
processTagName(name){
|
||||
if(name === "__proto__") name = "#__proto__";
|
||||
name = resolveNameSpace(name, this.removeNSPrefix);
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tags path from tagsStack
|
||||
*/
|
||||
tagsPath(tagName){
|
||||
//TODO: return TagPath Object. User can call match method with path
|
||||
return "";
|
||||
}
|
||||
|
||||
isUnpaired(tagName){
|
||||
return this.options.tags.unpaired.indexOf(tagName) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* valid expressions are
|
||||
* tag nested
|
||||
* * nested
|
||||
* tag nested[attribute]
|
||||
* tag nested[attribute=""]
|
||||
* tag nested[attribute!=""]
|
||||
* tag nested:0 //for future
|
||||
* @param {string} tagName
|
||||
* @returns
|
||||
*/
|
||||
isStopNode(node){
|
||||
for (let i = 0; i < this.stopNodes.length; i++) {
|
||||
const givenPath = this.stopNodes[i];
|
||||
if(givenPath.match(this.tagsStack, node)) return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
replaceEntities(text){
|
||||
//TODO: if option is set then replace entities
|
||||
return this.entityParser.parse(text)
|
||||
}
|
||||
}
|
||||
|
||||
function resolveNameSpace(name, removeNSPrefix) {
|
||||
if (removeNSPrefix) {
|
||||
const parts = name.split(':');
|
||||
if(parts.length === 2){
|
||||
if (parts[0] === 'xmlns') return '';
|
||||
else return parts[1];
|
||||
}else reportError(`Multiple namespaces ${name}`)
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
module.exports = Xml2JsParser;
|
216
em2rp/node_modules/fast-xml-parser/src/v5/XmlPartReader.js
generated
vendored
Normal file
216
em2rp/node_modules/fast-xml-parser/src/v5/XmlPartReader.js
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* find paired tag for a stop node
|
||||
* @param {string} xmlDoc
|
||||
* @param {string} tagName
|
||||
* @param {number} i : start index
|
||||
*/
|
||||
function readStopNode(xmlDoc, tagName, i){
|
||||
const startIndex = i;
|
||||
// Starting at 1 since we already have an open tag
|
||||
let openTagCount = 1;
|
||||
|
||||
for (; i < xmlDoc.length; i++) {
|
||||
if( xmlDoc[i] === "<"){
|
||||
if (xmlDoc[i+1] === "/") {//close tag
|
||||
const closeIndex = findSubStrIndex(xmlDoc, ">", i, `${tagName} is not closed`);
|
||||
let closeTagName = xmlDoc.substring(i+2,closeIndex).trim();
|
||||
if(closeTagName === tagName){
|
||||
openTagCount--;
|
||||
if (openTagCount === 0) {
|
||||
return {
|
||||
tagContent: xmlDoc.substring(startIndex, i),
|
||||
i : closeIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
i=closeIndex;
|
||||
} else if(xmlDoc[i+1] === '?') {
|
||||
const closeIndex = findSubStrIndex(xmlDoc, "?>", i+1, "StopNode is not closed.")
|
||||
i=closeIndex;
|
||||
} else if(xmlDoc.substr(i + 1, 3) === '!--') {
|
||||
const closeIndex = findSubStrIndex(xmlDoc, "-->", i+3, "StopNode is not closed.")
|
||||
i=closeIndex;
|
||||
} else if(xmlDoc.substr(i + 1, 2) === '![') {
|
||||
const closeIndex = findSubStrIndex(xmlDoc, "]]>", i, "StopNode is not closed.") - 2;
|
||||
i=closeIndex;
|
||||
} else {
|
||||
const tagData = readTagExp(xmlDoc, i, '>')
|
||||
|
||||
if (tagData) {
|
||||
const openTagName = tagData && tagData.tagName;
|
||||
if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") {
|
||||
openTagCount++;
|
||||
}
|
||||
i=tagData.closeIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end for loop
|
||||
}
|
||||
|
||||
/**
|
||||
* Read closing tag name
|
||||
* @param {Source} source
|
||||
* @returns tag name
|
||||
*/
|
||||
function readClosingTagName(source){
|
||||
let text = ""; //temporary data
|
||||
while(source.canRead()){
|
||||
let ch = source.readCh();
|
||||
// if (ch === null || ch === undefined) break;
|
||||
// source.updateBuffer();
|
||||
|
||||
if (ch === ">") return text.trimEnd();
|
||||
else text += ch;
|
||||
}
|
||||
throw new Error(`Unexpected end of source. Reading '${substr}'`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read XML tag and build attributes map
|
||||
* This function can be used to read normal tag, pi tag.
|
||||
* This function can't be used to read comment, CDATA, DOCTYPE.
|
||||
* Eg <tag attr = ' some"' attr= ">" bool>
|
||||
* @param {string} xmlDoc
|
||||
* @param {number} startIndex starting index
|
||||
* @returns tag expression includes tag name & attribute string
|
||||
*/
|
||||
function readTagExp(parser) {
|
||||
let inSingleQuotes = false;
|
||||
let inDoubleQuotes = false;
|
||||
let i;
|
||||
let EOE = false;
|
||||
|
||||
for (i = 0; parser.source.canRead(i); i++) {
|
||||
const char = parser.source.readChAt(i);
|
||||
|
||||
if (char === "'" && !inDoubleQuotes) {
|
||||
inSingleQuotes = !inSingleQuotes;
|
||||
} else if (char === '"' && !inSingleQuotes) {
|
||||
inDoubleQuotes = !inDoubleQuotes;
|
||||
} else if (char === '>' && !inSingleQuotes && !inDoubleQuotes) {
|
||||
// If not inside quotes, stop reading at '>'
|
||||
EOE = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if(inSingleQuotes || inDoubleQuotes){
|
||||
throw new Error("Invalid attribute expression. Quote is not properly closed");
|
||||
}else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '>'");
|
||||
|
||||
|
||||
const exp = parser.source.readStr(i);
|
||||
parser.source.updateBufferBoundary(i + 1);
|
||||
return buildTagExpObj(exp, parser)
|
||||
}
|
||||
|
||||
function readPiExp(parser) {
|
||||
let inSingleQuotes = false;
|
||||
let inDoubleQuotes = false;
|
||||
let i;
|
||||
let EOE = false;
|
||||
|
||||
for (i = 0; parser.source.canRead(i) ; i++) {
|
||||
const currentChar = parser.source.readChAt(i);
|
||||
const nextChar = parser.source.readChAt(i+1);
|
||||
|
||||
if (currentChar === "'" && !inDoubleQuotes) {
|
||||
inSingleQuotes = !inSingleQuotes;
|
||||
} else if (currentChar === '"' && !inSingleQuotes) {
|
||||
inDoubleQuotes = !inDoubleQuotes;
|
||||
}
|
||||
|
||||
if (!inSingleQuotes && !inDoubleQuotes) {
|
||||
if (currentChar === '?' && nextChar === '>') {
|
||||
EOE = true;
|
||||
break; // Exit the loop when '?>' is found
|
||||
}
|
||||
}
|
||||
}
|
||||
if(inSingleQuotes || inDoubleQuotes){
|
||||
throw new Error("Invalid attribute expression. Quote is not properly closed in PI tag expression");
|
||||
}else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '?>'");
|
||||
|
||||
if(!parser.options.attributes.ignore){
|
||||
//TODO: use regex to verify attributes if not set to ignore
|
||||
}
|
||||
|
||||
const exp = parser.source.readStr(i);
|
||||
parser.source.updateBufferBoundary(i + 1);
|
||||
return buildTagExpObj(exp, parser)
|
||||
}
|
||||
|
||||
function buildTagExpObj(exp, parser){
|
||||
const tagExp = {
|
||||
tagName: "",
|
||||
selfClosing: false
|
||||
};
|
||||
let attrsExp = "";
|
||||
|
||||
// Check for self-closing tag before setting the name
|
||||
if(exp[exp.length -1] === "/") {
|
||||
tagExp.selfClosing = true;
|
||||
exp = exp.slice(0, -1); // Remove the trailing slash
|
||||
}
|
||||
|
||||
//separate tag name
|
||||
let i = 0;
|
||||
for (; i < exp.length; i++) {
|
||||
const char = exp[i];
|
||||
if(char === " "){
|
||||
tagExp.tagName = exp.substring(0, i);
|
||||
attrsExp = exp.substring(i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//only tag
|
||||
if(tagExp.tagName.length === 0 && i === exp.length)tagExp.tagName = exp;
|
||||
|
||||
tagExp.tagName = tagExp.tagName.trimEnd();
|
||||
|
||||
if(!parser.options.attributes.ignore && attrsExp.length > 0){
|
||||
parseAttributesExp(attrsExp,parser)
|
||||
}
|
||||
|
||||
return tagExp;
|
||||
}
|
||||
|
||||
const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm');
|
||||
|
||||
function parseAttributesExp(attrStr, parser) {
|
||||
const matches = getAllMatches(attrStr, attrsRegx);
|
||||
const len = matches.length; //don't make it inline
|
||||
for (let i = 0; i < len; i++) {
|
||||
let attrName = parser.processAttrName(matches[i][1]);
|
||||
let attrVal = parser.replaceEntities(matches[i][4] || true);
|
||||
|
||||
parser.outputBuilder.addAttribute(attrName, attrVal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const getAllMatches = function(string, regex) {
|
||||
const matches = [];
|
||||
let match = regex.exec(string);
|
||||
while (match) {
|
||||
const allmatches = [];
|
||||
allmatches.startIndex = regex.lastIndex - match[0].length;
|
||||
const len = match.length;
|
||||
for (let index = 0; index < len; index++) {
|
||||
allmatches.push(match[index]);
|
||||
}
|
||||
matches.push(allmatches);
|
||||
match = regex.exec(string);
|
||||
}
|
||||
return matches;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
readStopNode: readStopNode,
|
||||
readClosingTagName: readClosingTagName,
|
||||
readTagExp: readTagExp,
|
||||
readPiExp: readPiExp,
|
||||
}
|
118
em2rp/node_modules/fast-xml-parser/src/v5/XmlSpecialTagsReader.js
generated
vendored
Normal file
118
em2rp/node_modules/fast-xml-parser/src/v5/XmlSpecialTagsReader.js
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
const {readPiExp} = require("./XmlPartReader");
|
||||
|
||||
function readCdata(parser){
|
||||
//<![ are already read till this point
|
||||
let str = parser.source.readStr(6); //CDATA[
|
||||
parser.source.updateBufferBoundary(6);
|
||||
|
||||
if(str !== "CDATA[") throw new Error(`Invalid CDATA expression at ${parser.source.line}:${parser.source.cols}`);
|
||||
|
||||
let text = parser.source.readUpto("]]>");
|
||||
parser.outputBuilder.addCdata(text);
|
||||
}
|
||||
function readPiTag(parser){
|
||||
//<? are already read till this point
|
||||
let tagExp = readPiExp(parser, "?>");
|
||||
if(!tagExp) throw new Error("Invalid Pi Tag expression.");
|
||||
|
||||
if (tagExp.tagName === "?xml") {//TODO: test if tagName is just xml
|
||||
parser.outputBuilder.addDeclaration();
|
||||
} else {
|
||||
parser.outputBuilder.addPi("?"+tagExp.tagName);
|
||||
}
|
||||
}
|
||||
|
||||
function readComment(parser){
|
||||
//<!- are already read till this point
|
||||
let ch = parser.source.readCh();
|
||||
if(ch !== "-") throw new Error(`Invalid comment expression at ${parser.source.line}:${parser.source.cols}`);
|
||||
|
||||
let text = parser.source.readUpto("-->");
|
||||
parser.outputBuilder.addComment(text);
|
||||
}
|
||||
|
||||
const DOCTYPE_tags = {
|
||||
"EL":/^EMENT\s+([^\s>]+)\s+(ANY|EMPTY|\(.+\)\s*$)/m,
|
||||
"AT":/^TLIST\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+$/m,
|
||||
"NO":/^TATION.+$/m
|
||||
}
|
||||
function readDocType(parser){
|
||||
//<!D are already read till this point
|
||||
let str = parser.source.readStr(6); //OCTYPE
|
||||
parser.source.updateBufferBoundary(6);
|
||||
|
||||
if(str !== "OCTYPE") throw new Error(`Invalid DOCTYPE expression at ${parser.source.line}:${parser.source.cols}`);
|
||||
|
||||
let hasBody = false, lastch = "";
|
||||
|
||||
while(parser.source.canRead()){
|
||||
//TODO: use readChAt like used in partReader
|
||||
let ch = parser.source.readCh();
|
||||
if(hasBody){
|
||||
if (ch === '<') { //Determine the tag type
|
||||
let str = parser.source.readStr(2);
|
||||
parser.source.updateBufferBoundary(2);
|
||||
if(str === "EN"){ //ENTITY
|
||||
let str = parser.source.readStr(4);
|
||||
parser.source.updateBufferBoundary(4);
|
||||
if(str !== "TITY") throw new Error("Invalid DOCTYPE ENTITY expression");
|
||||
|
||||
registerEntity(parser);
|
||||
}else if(str === "!-") {//comment
|
||||
readComment(parser);
|
||||
}else{ //ELEMENT, ATTLIST, NOTATION
|
||||
let dTagExp = parser.source.readUpto(">");
|
||||
const regx = DOCTYPE_tags[str];
|
||||
if(regx){
|
||||
const match = dTagExp.match(regx);
|
||||
if(!match) throw new Error("Invalid DOCTYPE");
|
||||
}else throw new Error("Invalid DOCTYPE");
|
||||
}
|
||||
}else if( ch === '>' && lastch === "]"){//end of doctype
|
||||
return;
|
||||
}
|
||||
}else if( ch === '>'){//end of doctype
|
||||
return;
|
||||
}else if( ch === '['){
|
||||
hasBody = true;
|
||||
}else{
|
||||
lastch = ch;
|
||||
}
|
||||
}//End While loop
|
||||
|
||||
}
|
||||
|
||||
function registerEntity(parser){
|
||||
//read Entity
|
||||
let attrBoundary="";
|
||||
let name ="", val ="";
|
||||
while(source.canRead()){
|
||||
let ch = source.readCh();
|
||||
|
||||
if(attrBoundary){
|
||||
if (ch === attrBoundary){
|
||||
val = text;
|
||||
text = ""
|
||||
}
|
||||
}else if(ch === " " || ch === "\t"){
|
||||
if(!name){
|
||||
name = text.trimStart();
|
||||
text = "";
|
||||
}
|
||||
}else if (ch === '"' || ch === "'") {//start of attrBoundary
|
||||
attrBoundary = ch;
|
||||
}else if(ch === ">"){
|
||||
parser.entityParser.addExternalEntity(name,val);
|
||||
return;
|
||||
}else{
|
||||
text+=ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
readCdata: readCdata,
|
||||
readComment:readComment,
|
||||
readDocType:readDocType,
|
||||
readPiTag:readPiTag
|
||||
}
|
118
em2rp/node_modules/fast-xml-parser/src/v5/inputSource/BufferSource.js
generated
vendored
Normal file
118
em2rp/node_modules/fast-xml-parser/src/v5/inputSource/BufferSource.js
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
const Constants = {
|
||||
space: 32,
|
||||
tab: 9
|
||||
}
|
||||
class BufferSource{
|
||||
constructor(bytesArr){
|
||||
this.line = 1;
|
||||
this.cols = 0;
|
||||
this.buffer = bytesArr;
|
||||
this.startIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
readCh() {
|
||||
return String.fromCharCode(this.buffer[this.startIndex++]);
|
||||
}
|
||||
|
||||
readChAt(index) {
|
||||
return String.fromCharCode(this.buffer[this.startIndex+index]);
|
||||
}
|
||||
|
||||
readStr(n,from){
|
||||
if(typeof from === "undefined") from = this.startIndex;
|
||||
return this.buffer.slice(from, from + n).toString();
|
||||
}
|
||||
|
||||
readUpto(stopStr) {
|
||||
const inputLength = this.buffer.length;
|
||||
const stopLength = stopStr.length;
|
||||
const stopBuffer = Buffer.from(stopStr);
|
||||
|
||||
for (let i = this.startIndex; i < inputLength; i++) {
|
||||
let match = true;
|
||||
for (let j = 0; j < stopLength; j++) {
|
||||
if (this.buffer[i + j] !== stopBuffer[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
const result = this.buffer.slice(this.startIndex, i).toString();
|
||||
this.startIndex = i + stopLength;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unexpected end of source. Reading '${stopStr}'`);
|
||||
}
|
||||
|
||||
readUptoCloseTag(stopStr) { //stopStr: "</tagname"
|
||||
const inputLength = this.buffer.length;
|
||||
const stopLength = stopStr.length;
|
||||
const stopBuffer = Buffer.from(stopStr);
|
||||
let stopIndex = 0;
|
||||
//0: non-matching, 1: matching stop string, 2: matching closing
|
||||
let match = 0;
|
||||
|
||||
for (let i = this.startIndex; i < inputLength; i++) {
|
||||
if(match === 1){//initial part matched
|
||||
if(stopIndex === 0) stopIndex = i;
|
||||
if(this.buffer[i] === Constants.space || this.buffer[i] === Constants.tab) continue;
|
||||
else if(this.buffer[i] === '>'){ //TODO: if it should be equivalent ASCII
|
||||
match = 2;
|
||||
//tag boundary found
|
||||
// this.startIndex
|
||||
}
|
||||
}else{
|
||||
match = 1;
|
||||
for (let j = 0; j < stopLength; j++) {
|
||||
if (this.buffer[i + j] !== stopBuffer[j]) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match === 2) {//matched closing part
|
||||
const result = this.buffer.slice(this.startIndex, stopIndex - 1 ).toString();
|
||||
this.startIndex = i + 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unexpected end of source. Reading '${stopStr}'`);
|
||||
}
|
||||
|
||||
readFromBuffer(n, shouldUpdate) {
|
||||
let ch;
|
||||
if (n === 1) {
|
||||
ch = this.buffer[this.startIndex];
|
||||
if (ch === 10) {
|
||||
this.line++;
|
||||
this.cols = 1;
|
||||
} else {
|
||||
this.cols++;
|
||||
}
|
||||
ch = String.fromCharCode(ch);
|
||||
} else {
|
||||
this.cols += n;
|
||||
ch = this.buffer.slice(this.startIndex, this.startIndex + n).toString();
|
||||
}
|
||||
if (shouldUpdate) this.updateBuffer(n);
|
||||
return ch;
|
||||
}
|
||||
|
||||
updateBufferBoundary(n = 1) { //n: number of characters read
|
||||
this.startIndex += n;
|
||||
}
|
||||
|
||||
canRead(n){
|
||||
n = n || this.startIndex;
|
||||
return this.buffer.length - n + 1 > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = BufferSource;
|
123
em2rp/node_modules/fast-xml-parser/src/v5/inputSource/StringSource.js
generated
vendored
Normal file
123
em2rp/node_modules/fast-xml-parser/src/v5/inputSource/StringSource.js
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
const whiteSpaces = [" ", "\n", "\t"];
|
||||
|
||||
|
||||
class StringSource{
|
||||
constructor(str){
|
||||
this.line = 1;
|
||||
this.cols = 0;
|
||||
this.buffer = str;
|
||||
//a boundary pointer to indicate where from the buffer dat should be read
|
||||
// data before this pointer can be deleted to free the memory
|
||||
this.startIndex = 0;
|
||||
}
|
||||
|
||||
readCh() {
|
||||
return this.buffer[this.startIndex++];
|
||||
}
|
||||
|
||||
readChAt(index) {
|
||||
return this.buffer[this.startIndex+index];
|
||||
}
|
||||
|
||||
readStr(n,from){
|
||||
if(typeof from === "undefined") from = this.startIndex;
|
||||
return this.buffer.substring(from, from + n);
|
||||
}
|
||||
|
||||
readUpto(stopStr) {
|
||||
const inputLength = this.buffer.length;
|
||||
const stopLength = stopStr.length;
|
||||
|
||||
for (let i = this.startIndex; i < inputLength; i++) {
|
||||
let match = true;
|
||||
for (let j = 0; j < stopLength; j++) {
|
||||
if (this.buffer[i + j] !== stopStr[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
const result = this.buffer.substring(this.startIndex, i);
|
||||
this.startIndex = i + stopLength;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unexpected end of source. Reading '${stopStr}'`);
|
||||
}
|
||||
|
||||
readUptoCloseTag(stopStr) { //stopStr: "</tagname"
|
||||
const inputLength = this.buffer.length;
|
||||
const stopLength = stopStr.length;
|
||||
let stopIndex = 0;
|
||||
//0: non-matching, 1: matching stop string, 2: matching closing
|
||||
let match = 0;
|
||||
|
||||
for (let i = this.startIndex; i < inputLength; i++) {
|
||||
if(match === 1){//initial part matched
|
||||
if(stopIndex === 0) stopIndex = i;
|
||||
if(this.buffer[i] === ' ' || this.buffer[i] === '\t') continue;
|
||||
else if(this.buffer[i] === '>'){
|
||||
match = 2;
|
||||
//tag boundary found
|
||||
// this.startIndex
|
||||
}
|
||||
}else{
|
||||
match = 1;
|
||||
for (let j = 0; j < stopLength; j++) {
|
||||
if (this.buffer[i + j] !== stopStr[j]) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match === 2) {//matched closing part
|
||||
const result = this.buffer.substring(this.startIndex, stopIndex - 1 );
|
||||
this.startIndex = i + 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unexpected end of source. Reading '${stopStr}'`);
|
||||
}
|
||||
|
||||
readFromBuffer(n, updateIndex){
|
||||
let ch;
|
||||
if(n===1){
|
||||
ch = this.buffer[this.startIndex];
|
||||
// if(ch === "\n") {
|
||||
// this.line++;
|
||||
// this.cols = 1;
|
||||
// }else{
|
||||
// this.cols++;
|
||||
// }
|
||||
}else{
|
||||
ch = this.buffer.substring(this.startIndex, this.startIndex + n);
|
||||
// if("".indexOf("\n") !== -1){
|
||||
// //TODO: handle the scenario when there are multiple lines
|
||||
// //TODO: col should be set to number of chars after last '\n'
|
||||
// // this.cols = 1;
|
||||
// }else{
|
||||
// this.cols += n;
|
||||
|
||||
// }
|
||||
}
|
||||
if(updateIndex) this.updateBufferBoundary(n);
|
||||
return ch;
|
||||
}
|
||||
|
||||
//TODO: rename to updateBufferReadIndex
|
||||
|
||||
updateBufferBoundary(n = 1) { //n: number of characters read
|
||||
this.startIndex += n;
|
||||
}
|
||||
|
||||
canRead(n){
|
||||
n = n || this.startIndex;
|
||||
return this.buffer.length - n + 1 > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = StringSource;
|
107
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/EntitiesParser.js
generated
vendored
Normal file
107
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/EntitiesParser.js
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"};
|
||||
const htmlEntities = {
|
||||
"space": { regex: /&(nbsp|#160);/g, val: " " },
|
||||
// "lt" : { regex: /&(lt|#60);/g, val: "<" },
|
||||
// "gt" : { regex: /&(gt|#62);/g, val: ">" },
|
||||
// "amp" : { regex: /&(amp|#38);/g, val: "&" },
|
||||
// "quot" : { regex: /&(quot|#34);/g, val: "\"" },
|
||||
// "apos" : { regex: /&(apos|#39);/g, val: "'" },
|
||||
"cent" : { regex: /&(cent|#162);/g, val: "¢" },
|
||||
"pound" : { regex: /&(pound|#163);/g, val: "£" },
|
||||
"yen" : { regex: /&(yen|#165);/g, val: "¥" },
|
||||
"euro" : { regex: /&(euro|#8364);/g, val: "€" },
|
||||
"copyright" : { regex: /&(copy|#169);/g, val: "©" },
|
||||
"reg" : { regex: /&(reg|#174);/g, val: "®" },
|
||||
"inr" : { regex: /&(inr|#8377);/g, val: "₹" },
|
||||
"num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) },
|
||||
"num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) },
|
||||
};
|
||||
|
||||
class EntitiesParser{
|
||||
constructor(replaceHtmlEntities) {
|
||||
this.replaceHtmlEntities = replaceHtmlEntities;
|
||||
this.docTypeEntities = {};
|
||||
this.lastEntities = {
|
||||
"apos" : { regex: /&(apos|#39|#x27);/g, val : "'"},
|
||||
"gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"},
|
||||
"lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"},
|
||||
"quot" : { regex: /&(quot|#34|#x22);/g, val : "\""},
|
||||
};
|
||||
}
|
||||
|
||||
addExternalEntities(externalEntities){
|
||||
const entKeys = Object.keys(externalEntities);
|
||||
for (let i = 0; i < entKeys.length; i++) {
|
||||
const ent = entKeys[i];
|
||||
this.addExternalEntity(ent,externalEntities[ent])
|
||||
}
|
||||
}
|
||||
addExternalEntity(key,val){
|
||||
validateEntityName(key);
|
||||
if(val.indexOf("&") !== -1) {
|
||||
reportWarning(`Entity ${key} is not added as '&' is found in value;`)
|
||||
return;
|
||||
}else{
|
||||
this.lastEntities[ent] = {
|
||||
regex: new RegExp("&"+key+";","g"),
|
||||
val : val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addDocTypeEntities(entities){
|
||||
const entKeys = Object.keys(entities);
|
||||
for (let i = 0; i < entKeys.length; i++) {
|
||||
const ent = entKeys[i];
|
||||
this.docTypeEntities[ent] = {
|
||||
regex: new RegExp("&"+ent+";","g"),
|
||||
val : entities[ent]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parse(val){
|
||||
return this.replaceEntitiesValue(val)
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Replace DOCTYPE entities
|
||||
* 2. Replace external entities
|
||||
* 3. Replace HTML entities if asked
|
||||
* @param {string} val
|
||||
*/
|
||||
replaceEntitiesValue(val){
|
||||
if(typeof val === "string" && val.length > 0){
|
||||
for(let entityName in this.docTypeEntities){
|
||||
const entity = this.docTypeEntities[entityName];
|
||||
val = val.replace( entity.regx, entity.val);
|
||||
}
|
||||
for(let entityName in this.lastEntities){
|
||||
const entity = this.lastEntities[entityName];
|
||||
val = val.replace( entity.regex, entity.val);
|
||||
}
|
||||
if(this.replaceHtmlEntities){
|
||||
for(let entityName in htmlEntities){
|
||||
const entity = htmlEntities[entityName];
|
||||
val = val.replace( entity.regex, entity.val);
|
||||
}
|
||||
}
|
||||
val = val.replace( ampEntity.regex, ampEntity.val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
//an entity name should not contains special characters that may be used in regex
|
||||
//Eg !?\\\/[]$%{}^&*()<>
|
||||
const specialChar = "!?\\\/[]$%{}^&*()<>|+";
|
||||
|
||||
function validateEntityName(name){
|
||||
for (let i = 0; i < specialChar.length; i++) {
|
||||
const ch = specialChar[i];
|
||||
if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
module.exports = EntitiesParser;
|
23
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParser.js
generated
vendored
Normal file
23
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParser.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
class boolParser{
|
||||
constructor(trueList, falseList){
|
||||
if(trueList)
|
||||
this.trueList = trueList;
|
||||
else
|
||||
this.trueList = ["true"];
|
||||
|
||||
if(falseList)
|
||||
this.falseList = falseList;
|
||||
else
|
||||
this.falseList = ["false"];
|
||||
}
|
||||
parse(val){
|
||||
if (typeof val === 'string') {
|
||||
//TODO: performance: don't convert
|
||||
const temp = val.toLowerCase();
|
||||
if(this.trueList.indexOf(temp) !== -1) return true;
|
||||
else if(this.falseList.indexOf(temp) !== -1 ) return false;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
module.exports = boolParser;
|
20
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParserExt.js
generated
vendored
Normal file
20
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParserExt.js
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
function boolParserExt(val){
|
||||
if(isArray(val)){
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
val[i] = parse(val[i])
|
||||
}
|
||||
}else{
|
||||
val = parse(val)
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
function parse(val){
|
||||
if (typeof val === 'string') {
|
||||
const temp = val.toLowerCase();
|
||||
if(temp === 'true' || temp ==="yes" || temp==="1") return true;
|
||||
else if(temp === 'false' || temp ==="no" || temp==="0") return false;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
module.exports = boolParserExt;
|
40
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/currency.js
generated
vendored
Normal file
40
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/currency.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
const defaultOptions = {
|
||||
maxLength: 200,
|
||||
// locale: "en-IN"
|
||||
}
|
||||
const localeMap = {
|
||||
"$":"en-US",
|
||||
"€":"de-DE",
|
||||
"£":"en-GB",
|
||||
"¥":"ja-JP",
|
||||
"₹":"en-IN",
|
||||
}
|
||||
const sign = "(?:-|\+)?";
|
||||
const digitsAndSeparator = "(?:\d+|\d{1,3}(?:,\d{3})+)";
|
||||
const decimalPart = "(?:\.\d{1,2})?";
|
||||
const symbol = "(?:\$|€|¥|₹)?";
|
||||
|
||||
const currencyCheckRegex = /^\s*(?:-|\+)?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d{1,2})?\s*(?:\$|€|¥|₹)?\s*$/u;
|
||||
|
||||
class CurrencyParser{
|
||||
constructor(options){
|
||||
this.options = options || defaultOptions;
|
||||
}
|
||||
parse(val){
|
||||
if (typeof val === 'string' && val.length <= this.options.maxLength) {
|
||||
if(val.indexOf(",,") !== -1 && val.indexOf(".." !== -1)){
|
||||
const match = val.match(currencyCheckRegex);
|
||||
if(match){
|
||||
const locale = this.options.locale || localeMap[match[2]||match[5]||"₹"];
|
||||
const formatter = new Intl.NumberFormat(locale)
|
||||
val = val.replace(/[^0-9,.]/g, '').trim();
|
||||
val = Number(val.replace(formatter.format(1000)[1], ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
CurrencyParser.defaultOptions = defaultOptions;
|
||||
|
||||
module.exports = CurrencyParser;
|
14
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/join.js
generated
vendored
Normal file
14
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/join.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
*
|
||||
* @param {array} val
|
||||
* @param {string} by
|
||||
* @returns
|
||||
*/
|
||||
function join(val, by=" "){
|
||||
if(isArray(val)){
|
||||
val.join(by)
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
module.exports = join;
|
16
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/number.js
generated
vendored
Normal file
16
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/number.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
const toNumber = require("strnum");
|
||||
|
||||
|
||||
class numParser{
|
||||
constructor(options){
|
||||
this.options = options;
|
||||
}
|
||||
parse(val){
|
||||
if (typeof val === 'string') {
|
||||
val = toNumber(val,this.options);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = numParser;
|
8
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/trim.js
generated
vendored
Normal file
8
em2rp/node_modules/fast-xml-parser/src/v5/valueParsers/trim.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
class trimmer{
|
||||
parse(val){
|
||||
if(typeof val === "string") return val.trim();
|
||||
else return val;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = trimmer;
|
Reference in New Issue
Block a user