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 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",
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": "^5.16.0",
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": "^4.46.0",
57
- "webpack-cli": "^3.3.12"
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.4"
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: "&apos;" },
28
28
  "dQuot" : { regex: new RegExp("\"", "g"), val: "&quot;" }
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 = options.tagValueProcessor( tagName, tagObj[tagName]);
27
- tagText = replaceEntitiesValue(tagText, options);
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 '&#xD;'")
50
+ }else{
51
+ this.externalEntities[key] = value;
52
+ }
53
+ }
35
54
  }
36
55
 
37
56
  module.exports = XMLParser;