fast-xml-parser 5.7.2 → 5.8.0
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 +16 -0
- package/README.md +2 -7
- package/lib/fxbuilder.min.js +1 -1
- package/lib/fxbuilder.min.js.map +1 -1
- package/lib/fxp.cjs +1 -1
- package/lib/fxp.d.cts +1 -0
- package/lib/fxp.min.js +1 -1
- package/lib/fxp.min.js.map +1 -1
- package/lib/fxparser.min.js +1 -1
- package/lib/fxparser.min.js.map +1 -1
- package/package.json +5 -5
- package/src/fxp.d.ts +13 -1
- package/src/xmlparser/DocTypeReader.js +14 -10
- package/src/xmlparser/OrderedObjParser.js +2 -4
- package/src/xmlparser/node2json.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-xml-parser",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
4
|
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
|
|
5
5
|
"main": "./lib/fxp.cjs",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"test": "c8 --reporter=lcov --reporter=text jasmine spec/*spec.js",
|
|
24
24
|
"test-types": "tsc --noEmit spec/typings/typings-test.ts",
|
|
25
25
|
"unit": "jasmine",
|
|
26
|
-
"coverage": "nyc report --reporter html --reporter text -t .nyc_output --report-dir .nyc_output/summary",
|
|
27
26
|
"perf": "node ./benchmark/perfTest3.js",
|
|
28
27
|
"lint": "eslint src/**/*.js spec/**/*.js benchmark/**/*.js",
|
|
29
28
|
"bundle": "webpack --config webpack.cjs.config.js",
|
|
@@ -68,11 +67,11 @@
|
|
|
68
67
|
"@babel/plugin-transform-runtime": "^7.13.10",
|
|
69
68
|
"@babel/preset-env": "^7.13.10",
|
|
70
69
|
"@babel/register": "^7.13.8",
|
|
70
|
+
"@byspec/xml": "^0.1.0",
|
|
71
71
|
"@types/node": "20",
|
|
72
72
|
"babel-loader": "^8.2.2",
|
|
73
73
|
"c8": "^10.1.3",
|
|
74
74
|
"eslint": "^8.3.0",
|
|
75
|
-
"he": "^1.2.0",
|
|
76
75
|
"jasmine": "^5.6.0",
|
|
77
76
|
"prettier": "^3.5.1",
|
|
78
77
|
"publish-please": "^5.5.2",
|
|
@@ -88,8 +87,9 @@
|
|
|
88
87
|
],
|
|
89
88
|
"dependencies": {
|
|
90
89
|
"@nodable/entities": "^2.1.0",
|
|
91
|
-
"fast-xml-builder": "^1.
|
|
90
|
+
"fast-xml-builder": "^1.2.0",
|
|
92
91
|
"path-expression-matcher": "^1.5.0",
|
|
93
|
-
"strnum": "^2.
|
|
92
|
+
"strnum": "^2.3.0",
|
|
93
|
+
"xml-naming": "^0.1.0"
|
|
94
94
|
}
|
|
95
95
|
}
|
package/src/fxp.d.ts
CHANGED
|
@@ -696,11 +696,19 @@ export type ValidationError = {
|
|
|
696
696
|
|
|
697
697
|
export class XMLParser {
|
|
698
698
|
constructor(options?: X2jOptions);
|
|
699
|
-
|
|
699
|
+
|
|
700
|
+
parse(xmlData: string | Uint8Array): any;
|
|
701
|
+
/**
|
|
702
|
+
* @deprecated The `validationOptions` parameter is deprecated.
|
|
703
|
+
* Use the `fast-xml-validator` package instead for XML validation.
|
|
704
|
+
* @see https://www.npmjs.com/package/fast-xml-validator
|
|
705
|
+
*/
|
|
706
|
+
parse(xmlData: string | Uint8Array, validationOptions: validationOptions | boolean): any;
|
|
700
707
|
/**
|
|
701
708
|
* Add Entity which is not by default supported by this library
|
|
702
709
|
* @param entityIdentifier {string} Eg: 'ent' for &ent;
|
|
703
710
|
* @param entityValue {string} Eg: '\r'
|
|
711
|
+
* @deprecated Use `entityDecoder` instead
|
|
704
712
|
*/
|
|
705
713
|
addEntity(entityIdentifier: string, entityValue: string): void;
|
|
706
714
|
|
|
@@ -717,6 +725,10 @@ export class XMLParser {
|
|
|
717
725
|
static getMetaDataSymbol(): Symbol;
|
|
718
726
|
}
|
|
719
727
|
|
|
728
|
+
/**
|
|
729
|
+
* @deprecated Use fast-xml-validator instead
|
|
730
|
+
* @see https://www.npmjs.com/package/fast-xml-validator
|
|
731
|
+
*/
|
|
720
732
|
export class XMLValidator {
|
|
721
733
|
static validate(xmlData: string, options?: validationOptions): true | ValidationError;
|
|
722
734
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { isName } from '
|
|
1
|
+
import { qName as isName } from 'xml-naming';
|
|
2
2
|
|
|
3
3
|
export default class DocTypeReader {
|
|
4
|
-
constructor(options) {
|
|
4
|
+
constructor(options, xmlVersion) {
|
|
5
5
|
this.suppressValidationErr = !options;
|
|
6
6
|
this.options = options;
|
|
7
|
+
this.xmlVersion = xmlVersion || 1.0;
|
|
7
8
|
}
|
|
8
9
|
|
|
10
|
+
setXmlVersion(xmlVersion = 1.0) {
|
|
11
|
+
this.xmlVersion = xmlVersion;
|
|
12
|
+
}
|
|
9
13
|
readDocType(xmlData, i) {
|
|
10
14
|
const entities = Object.create(null);
|
|
11
15
|
let entityCount = 0;
|
|
@@ -103,7 +107,7 @@ export default class DocTypeReader {
|
|
|
103
107
|
}
|
|
104
108
|
let entityName = xmlData.substring(startIndex, i);
|
|
105
109
|
|
|
106
|
-
validateEntityName(entityName);
|
|
110
|
+
validateEntityName(entityName, { xmlVersion: this.xmlVersion });
|
|
107
111
|
|
|
108
112
|
// Skip whitespace after entity name
|
|
109
113
|
i = skipWhitespace(xmlData, i);
|
|
@@ -146,7 +150,7 @@ export default class DocTypeReader {
|
|
|
146
150
|
}
|
|
147
151
|
let notationName = xmlData.substring(startIndex, i);
|
|
148
152
|
|
|
149
|
-
!this.suppressValidationErr && validateEntityName(notationName);
|
|
153
|
+
!this.suppressValidationErr && validateEntityName(notationName, { xmlVersion: this.xmlVersion });
|
|
150
154
|
|
|
151
155
|
// Skip whitespace after notation name
|
|
152
156
|
i = skipWhitespace(xmlData, i);
|
|
@@ -226,7 +230,7 @@ export default class DocTypeReader {
|
|
|
226
230
|
let elementName = xmlData.substring(startIndex, i);
|
|
227
231
|
|
|
228
232
|
// Validate element name
|
|
229
|
-
if (!this.suppressValidationErr && !isName(elementName)) {
|
|
233
|
+
if (!this.suppressValidationErr && !isName(elementName, { xmlVersion: this.xmlVersion })) {
|
|
230
234
|
throw new Error(`Invalid element name: "${elementName}"`);
|
|
231
235
|
}
|
|
232
236
|
|
|
@@ -273,7 +277,7 @@ export default class DocTypeReader {
|
|
|
273
277
|
let elementName = xmlData.substring(startIndex, i);
|
|
274
278
|
|
|
275
279
|
// Validate element name
|
|
276
|
-
validateEntityName(elementName)
|
|
280
|
+
validateEntityName(elementName, { xmlVersion: this.xmlVersion })
|
|
277
281
|
|
|
278
282
|
// Skip whitespace after element name
|
|
279
283
|
i = skipWhitespace(xmlData, i);
|
|
@@ -286,7 +290,7 @@ export default class DocTypeReader {
|
|
|
286
290
|
let attributeName = xmlData.substring(startIndex, i);
|
|
287
291
|
|
|
288
292
|
// Validate attribute name
|
|
289
|
-
if (!validateEntityName(attributeName)) {
|
|
293
|
+
if (!validateEntityName(attributeName, { xmlVersion: this.xmlVersion })) {
|
|
290
294
|
throw new Error(`Invalid attribute name: "${attributeName}"`);
|
|
291
295
|
}
|
|
292
296
|
|
|
@@ -321,7 +325,7 @@ export default class DocTypeReader {
|
|
|
321
325
|
|
|
322
326
|
// Validate notation name
|
|
323
327
|
notation = notation.trim();
|
|
324
|
-
if (!validateEntityName(notation)) {
|
|
328
|
+
if (!validateEntityName(notation, { xmlVersion: this.xmlVersion })) {
|
|
325
329
|
throw new Error(`Invalid notation name: "${notation}"`);
|
|
326
330
|
}
|
|
327
331
|
|
|
@@ -399,8 +403,8 @@ function hasSeq(data, seq, i) {
|
|
|
399
403
|
return true;
|
|
400
404
|
}
|
|
401
405
|
|
|
402
|
-
function validateEntityName(name) {
|
|
403
|
-
if (isName(name))
|
|
406
|
+
function validateEntityName(name, xmlVersion) {
|
|
407
|
+
if (isName(name, { xmlVersion: xmlVersion }))
|
|
404
408
|
return name;
|
|
405
409
|
else
|
|
406
410
|
throw new Error(`Invalid entity name ${name}`);
|
|
@@ -105,9 +105,6 @@ export default class OrderedObjParser {
|
|
|
105
105
|
|
|
106
106
|
// Initialize path matcher for path-expression-matcher
|
|
107
107
|
this.matcher = new Matcher();
|
|
108
|
-
|
|
109
|
-
// Live read-only proxy of matcher — PEM creates and caches this internally.
|
|
110
|
-
// All user callbacks receive this instead of the mutable matcher.
|
|
111
108
|
this.readonlyMatcher = this.matcher.readOnly();
|
|
112
109
|
|
|
113
110
|
// Flag to track if current node is a stop node (optimization)
|
|
@@ -343,6 +340,7 @@ const parseXml = function (xmlData) {
|
|
|
343
340
|
if (attsMap) {
|
|
344
341
|
const ver = attsMap[this.options.attributeNamePrefix + "version"];
|
|
345
342
|
this.entityDecoder.setXmlVersion(Number(ver) || 1.0);
|
|
343
|
+
docTypeReader.setXmlVersion(Number(ver) || 1.0);
|
|
346
344
|
}
|
|
347
345
|
if ((options.ignoreDeclaration && tagData.tagName === "?xml") || options.ignorePiTags) {
|
|
348
346
|
//do nothing
|
|
@@ -776,7 +774,7 @@ function readStopNodeData(xmlData, tagName, i) {
|
|
|
776
774
|
const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
|
|
777
775
|
i = closeIndex;
|
|
778
776
|
} else {
|
|
779
|
-
const tagData = readTagExp(xmlData, i,
|
|
777
|
+
const tagData = readTagExp(xmlData, i, false)
|
|
780
778
|
|
|
781
779
|
if (tagData) {
|
|
782
780
|
const openTagName = tagData && tagData.tagName;
|
|
@@ -71,6 +71,10 @@ function compress(arr, options, matcher, readonlyMatcher) {
|
|
|
71
71
|
let val = compress(tagObj[property], options, matcher, readonlyMatcher);
|
|
72
72
|
const isLeaf = isLeafTag(val, options);
|
|
73
73
|
|
|
74
|
+
if (Object.keys(val).length === 0 && options.alwaysCreateTextNode) {
|
|
75
|
+
val[options.textNodeName] = "";
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
if (tagObj[":@"]) {
|
|
75
79
|
assignAttributes(val, tagObj[":@"], readonlyMatcher, options);
|
|
76
80
|
} else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {
|