fast-xml-parser 4.0.0-beta.3 → 4.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +2 -1
- package/package.json +5 -5
- package/src/fxp.d.ts +7 -0
- package/src/xmlbuilder/json2xml.js +3 -1
- package/src/xmlbuilder/orderedJs2Xml.js +20 -5
- package/src/xmlparser/OrderedObjParser.js +12 -0
- package/src/xmlparser/XMLParser.js +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.
|
|
2
2
|
|
|
3
|
+
** 4.0.0-beta.4 / 2021-12-02**
|
|
4
|
+
* Support HTML document parsing
|
|
5
|
+
* skip stop nodes parsing when building the XML from JS object
|
|
6
|
+
* Support external entites without DOCTYPE
|
|
7
|
+
* update dev dependency: strnum v1.0.5 to fix long number issue
|
|
8
|
+
|
|
3
9
|
** 4.0.0-beta.3 / 2021-11-30**
|
|
4
10
|
* support global stopNodes expression like "*.stop"
|
|
5
11
|
* support self-closing and paired unpaired tags
|
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ Check [ThankYouBackers](https://github.com/NaturalIntelligence/ThankYouBackers)
|
|
|
29
29
|
<a href="http://nasa.github.io/" title="NASA" > <img src="https://avatars0.githubusercontent.com/u/848102" width="60px" ></a>
|
|
30
30
|
<a href="https://github.com/prettier" title="Prettier" > <img src="https://avatars0.githubusercontent.com/u/25822731" width="60px" ></a>
|
|
31
31
|
<a href="http://brain.js.org/" title="brain.js" > <img src="https://avatars2.githubusercontent.com/u/23732838" width="60px" ></a>
|
|
32
|
+
<a href="https://github.com/aws" title="AWS SDK" > <img src="https://avatars.githubusercontent.com/u/2232217" width="60px" ></a>
|
|
32
33
|
<a href="#" title="NHS Connect" > <img src="https://avatars3.githubusercontent.com/u/20316669" width="60px" ></a>
|
|
33
34
|
<a href="http://www.fda.gov/" title="Food and Drug Administration " > <img src="https://avatars2.githubusercontent.com/u/6471964" width="60px" ></a>
|
|
34
35
|
<a href="http://www.magento.com/" title="Magento" > <img src="https://avatars2.githubusercontent.com/u/168457" width="60px" ></a>
|
|
@@ -106,7 +107,7 @@ In a HTML page
|
|
|
106
107
|
3. [XML Builder](./docs/v4/3.XMLBuilder.md)
|
|
107
108
|
4. [XML Validator](./docs/v4/4.XMLValidator.md)
|
|
108
109
|
5. [Entites](./docs/5.Entities.md)
|
|
109
|
-
|
|
110
|
+
6. [HTML Document Parsing](./docs/6.HTMLParsing.md)
|
|
110
111
|
## Performance
|
|
111
112
|
|
|
112
113
|
### XML Parser
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-xml-parser",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.4",
|
|
4
4
|
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
|
|
5
5
|
"main": "./src/fxp.js",
|
|
6
6
|
"scripts": {
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"@babel/preset-env": "^7.13.10",
|
|
48
48
|
"@babel/register": "^7.13.8",
|
|
49
49
|
"babel-loader": "^8.2.2",
|
|
50
|
-
"eslint": "^
|
|
50
|
+
"eslint": "^8.3.0",
|
|
51
51
|
"he": "^1.2.0",
|
|
52
52
|
"jasmine": "^3.6.4",
|
|
53
53
|
"nyc": "^15.1.0",
|
|
54
54
|
"prettier": "^1.19.1",
|
|
55
55
|
"publish-please": "^5.5.2",
|
|
56
|
-
"webpack": "^
|
|
57
|
-
"webpack-cli": "^
|
|
56
|
+
"webpack": "^5.64.4",
|
|
57
|
+
"webpack-cli": "^4.9.1"
|
|
58
58
|
},
|
|
59
59
|
"typings": "src/fxp.d.ts",
|
|
60
60
|
"funding": {
|
|
@@ -62,6 +62,6 @@
|
|
|
62
62
|
"url": "https://paypal.me/naturalintelligence"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"strnum": "^1.0.
|
|
65
|
+
"strnum": "^1.0.5"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/src/fxp.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ type XmlBuilderOptions = {
|
|
|
46
46
|
suppressEmptyNode: boolean;
|
|
47
47
|
preserveOrder: boolean;
|
|
48
48
|
unpairedTags: string[];
|
|
49
|
+
stopNodes: string[];
|
|
49
50
|
tagValueProcessor: (name: string, value: string) => string;
|
|
50
51
|
attributeValueProcessor: (name: string, value: string) => string;
|
|
51
52
|
processEntities: boolean;
|
|
@@ -66,6 +67,12 @@ type ValidationError = {
|
|
|
66
67
|
export class XMLParser {
|
|
67
68
|
constructor(options?: X2jOptionsOptional);
|
|
68
69
|
parse(xmlData: string | Buffer ,validationOptions?: validationOptionsOptional | boolean): any;
|
|
70
|
+
/**
|
|
71
|
+
* Add Entity which is not by default supported by this library
|
|
72
|
+
* @param entityIndentifier {string} Eg: 'ent' for &ent;
|
|
73
|
+
* @param entityValue {string} Eg: '\r'
|
|
74
|
+
*/
|
|
75
|
+
addEntity(entityIndentifier: string, entityValue: string): void;
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
export class XMLValidator{
|
|
@@ -27,7 +27,8 @@ const defaultOptions = {
|
|
|
27
27
|
"sQuot" : { regex: new RegExp("\'", "g"), val: "'" },
|
|
28
28
|
"dQuot" : { regex: new RegExp("\"", "g"), val: """ }
|
|
29
29
|
},
|
|
30
|
-
processEntities: true
|
|
30
|
+
processEntities: true,
|
|
31
|
+
stopNodes: []
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
const props = [
|
|
@@ -47,6 +48,7 @@ const props = [
|
|
|
47
48
|
"unpairedTags",
|
|
48
49
|
"entities",
|
|
49
50
|
"processEntities",
|
|
51
|
+
"stopNodes",
|
|
50
52
|
// 'rootNodeName', //when jsObject have multiple properties on root level
|
|
51
53
|
];
|
|
52
54
|
|
|
@@ -7,10 +7,10 @@ const {EOL} = require('os');
|
|
|
7
7
|
* @returns
|
|
8
8
|
*/
|
|
9
9
|
function toXml(jArray, options){
|
|
10
|
-
return arrToStr( jArray, options, 0);
|
|
10
|
+
return arrToStr( jArray, options, "", 0);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
function arrToStr(arr, options, level){
|
|
13
|
+
function arrToStr(arr, options, jPath, level){
|
|
14
14
|
let xmlStr = "";
|
|
15
15
|
|
|
16
16
|
let indentation = "";
|
|
@@ -21,10 +21,16 @@ function arrToStr(arr, options, level){
|
|
|
21
21
|
for (let i = 0; i < arr.length; i++) {
|
|
22
22
|
const tagObj = arr[i];
|
|
23
23
|
const tagName = propName(tagObj);
|
|
24
|
+
let newJPath = "";
|
|
25
|
+
if(jPath.length === 0) newJPath = tagName
|
|
26
|
+
else newJPath = `${jPath}.${tagName}`;
|
|
24
27
|
|
|
25
28
|
if(tagName === options.textNodeName){
|
|
26
|
-
let tagText =
|
|
27
|
-
|
|
29
|
+
let tagText = tagObj[tagName];
|
|
30
|
+
if(!isStopNode(newJPath, options)){
|
|
31
|
+
tagText = options.tagValueProcessor( tagName, tagText);
|
|
32
|
+
tagText = replaceEntitiesValue(tagText, options);
|
|
33
|
+
}
|
|
28
34
|
xmlStr += indentation + tagText;
|
|
29
35
|
continue;
|
|
30
36
|
}else if( tagName === options.cdataPropName){
|
|
@@ -36,7 +42,7 @@ function arrToStr(arr, options, level){
|
|
|
36
42
|
}
|
|
37
43
|
const attStr = attr_to_str(tagObj.attributes, options);
|
|
38
44
|
let tagStart = indentation + `<${tagName}${attStr}`;
|
|
39
|
-
let tagValue = arrToStr(tagObj[tagName], options, level + 1);
|
|
45
|
+
let tagValue = arrToStr(tagObj[tagName], options, newJPath, level + 1);
|
|
40
46
|
if( (!tagValue || tagValue.length === 0) && options.suppressEmptyNode){
|
|
41
47
|
if(options.unpairedTags.indexOf(tagName) !== -1){
|
|
42
48
|
xmlStr += tagStart + ">";
|
|
@@ -72,6 +78,15 @@ function attr_to_str(attrMap, options){
|
|
|
72
78
|
return attrStr;
|
|
73
79
|
}
|
|
74
80
|
|
|
81
|
+
function isStopNode(jPath, options){
|
|
82
|
+
jPath = jPath.substr(0,jPath.length - options.textNodeName.length - 1);
|
|
83
|
+
let tagName = jPath.substr(jPath.lastIndexOf(".") + 1);
|
|
84
|
+
for(let index in options.stopNodes){
|
|
85
|
+
if(options.stopNodes[index] === jPath || options.stopNodes[index] === "*."+tagName) return true;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
75
90
|
function replaceEntitiesValue(textValue, options){
|
|
76
91
|
if(textValue && textValue.length > 0 && options.processEntities){
|
|
77
92
|
for (const entityName in options.entities) {
|
|
@@ -40,6 +40,7 @@ class OrderedObjParser{
|
|
|
40
40
|
"reg" : { regex: /&(reg|#174);/g, val: "®" },
|
|
41
41
|
"inr" : { regex: /&(inr|#8377);/g, val: "₹" },
|
|
42
42
|
};
|
|
43
|
+
this.addExternalEntities = addExternalEntities;
|
|
43
44
|
this.parseXml = parseXml;
|
|
44
45
|
this.parseTextData = parseTextData;
|
|
45
46
|
this.resolveNameSpace = resolveNameSpace;
|
|
@@ -52,6 +53,17 @@ class OrderedObjParser{
|
|
|
52
53
|
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
function addExternalEntities(externalEntities){
|
|
57
|
+
const entKeys = Object.keys(externalEntities);
|
|
58
|
+
for (let i = 0; i < entKeys.length; i++) {
|
|
59
|
+
const ent = entKeys[i];
|
|
60
|
+
this.lastEntities[ent] = {
|
|
61
|
+
regex: new RegExp("&"+ent+";","g"),
|
|
62
|
+
val : externalEntities[ent]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
55
67
|
/**
|
|
56
68
|
* @param {string} val
|
|
57
69
|
* @param {string} tagName
|
|
@@ -4,8 +4,11 @@ const { prettify} = require("./node2json");
|
|
|
4
4
|
const validator = require('../validator');
|
|
5
5
|
|
|
6
6
|
class XMLParser{
|
|
7
|
+
|
|
7
8
|
constructor(options){
|
|
9
|
+
this.externalEntities = {};
|
|
8
10
|
this.options = buildOptions(options);
|
|
11
|
+
|
|
9
12
|
}
|
|
10
13
|
/**
|
|
11
14
|
* Parse XML dats to JS object
|
|
@@ -28,10 +31,26 @@ class XMLParser{
|
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
33
|
const orderedObjParser = new OrderedObjParser(this.options);
|
|
34
|
+
orderedObjParser.addExternalEntities(this.externalEntities);
|
|
31
35
|
const orderedResult = orderedObjParser.parseXml(xmlData);
|
|
32
36
|
if(this.options.preserveOrder || orderedResult === undefined) return orderedResult;
|
|
33
37
|
else return prettify(orderedResult, this.options);
|
|
34
38
|
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Add Entity which is not by default supported by this library
|
|
42
|
+
* @param {string} key
|
|
43
|
+
* @param {string} value
|
|
44
|
+
*/
|
|
45
|
+
addEntity(key, value){
|
|
46
|
+
if(value.indexOf("&") !== -1){
|
|
47
|
+
throw new Error("Entity value can't have '&'")
|
|
48
|
+
}else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){
|
|
49
|
+
throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'")
|
|
50
|
+
}else{
|
|
51
|
+
this.externalEntities[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
35
54
|
}
|
|
36
55
|
|
|
37
56
|
module.exports = XMLParser;
|