fast-xml-parser 5.7.1 → 5.7.3
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 +15 -0
- package/README.md +0 -3
- 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 +2 -4
- package/src/fxp.d.ts +1 -0
- package/src/xmlparser/OrderedObjParser.js +17 -12
- package/src/xmlparser/XMLParser.js +2 -2
- 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.7.
|
|
3
|
+
"version": "5.7.3",
|
|
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",
|
|
@@ -72,7 +71,6 @@
|
|
|
72
71
|
"babel-loader": "^8.2.2",
|
|
73
72
|
"c8": "^10.1.3",
|
|
74
73
|
"eslint": "^8.3.0",
|
|
75
|
-
"he": "^1.2.0",
|
|
76
74
|
"jasmine": "^5.6.0",
|
|
77
75
|
"prettier": "^3.5.1",
|
|
78
76
|
"publish-please": "^5.5.2",
|
|
@@ -88,7 +86,7 @@
|
|
|
88
86
|
],
|
|
89
87
|
"dependencies": {
|
|
90
88
|
"@nodable/entities": "^2.1.0",
|
|
91
|
-
"fast-xml-builder": "^1.1.
|
|
89
|
+
"fast-xml-builder": "^1.1.7",
|
|
92
90
|
"path-expression-matcher": "^1.5.0",
|
|
93
91
|
"strnum": "^2.2.3"
|
|
94
92
|
}
|
package/src/fxp.d.ts
CHANGED
|
@@ -701,6 +701,7 @@ export class XMLParser {
|
|
|
701
701
|
* Add Entity which is not by default supported by this library
|
|
702
702
|
* @param entityIdentifier {string} Eg: 'ent' for &ent;
|
|
703
703
|
* @param entityValue {string} Eg: '\r'
|
|
704
|
+
* @deprecated Use `entityDecoder` instead
|
|
704
705
|
*/
|
|
705
706
|
addEntity(entityIdentifier: string, entityValue: string): void;
|
|
706
707
|
|
|
@@ -69,7 +69,7 @@ function extractNamespace(rawTagName) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export default class OrderedObjParser {
|
|
72
|
-
constructor(options) {
|
|
72
|
+
constructor(options, externalEntities) {
|
|
73
73
|
this.options = options;
|
|
74
74
|
this.currentNode = null;
|
|
75
75
|
this.tagsNodeStack = [];
|
|
@@ -92,7 +92,7 @@ export default class OrderedObjParser {
|
|
|
92
92
|
if (typeof this.options.htmlEntities === "object") namedEntities = this.options.htmlEntities;
|
|
93
93
|
else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };
|
|
94
94
|
this.entityDecoder = new EntityDecoder({
|
|
95
|
-
namedEntities: namedEntities,
|
|
95
|
+
namedEntities: { ...namedEntities, ...externalEntities },
|
|
96
96
|
numericAllowed: this.options.htmlEntities,
|
|
97
97
|
limit: {
|
|
98
98
|
maxTotalExpansions: this.options.processEntities.maxTotalExpansions,
|
|
@@ -269,7 +269,7 @@ function buildAttributesMap(attrStr, jPath, tagName, force = false) {
|
|
|
269
269
|
|
|
270
270
|
if (!hasAttrs) return;
|
|
271
271
|
|
|
272
|
-
if (options.attributesGroupName) {
|
|
272
|
+
if (options.attributesGroupName && !options.preserveOrder) {
|
|
273
273
|
const attrCollection = {};
|
|
274
274
|
attrCollection[options.attributesGroupName] = attrs;
|
|
275
275
|
return attrCollection;
|
|
@@ -655,12 +655,16 @@ function isItStopNode() {
|
|
|
655
655
|
* @returns
|
|
656
656
|
*/
|
|
657
657
|
function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
|
|
658
|
+
//TODO: ignore boolean attributes in tag expression
|
|
659
|
+
//TODO: if ignore attributes, dont read full attribute expression but the end. But read for xml declaration
|
|
658
660
|
let attrBoundary = 0;
|
|
659
|
-
const chars = [];
|
|
660
661
|
const len = xmlData.length;
|
|
661
662
|
const closeCode0 = closingChar.charCodeAt(0);
|
|
662
663
|
const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;
|
|
663
664
|
|
|
665
|
+
let result = '';
|
|
666
|
+
let segmentStart = i;
|
|
667
|
+
|
|
664
668
|
for (let index = i; index < len; index++) {
|
|
665
669
|
const code = xmlData.charCodeAt(index);
|
|
666
670
|
|
|
@@ -671,17 +675,18 @@ function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
|
|
|
671
675
|
} else if (code === closeCode0) {
|
|
672
676
|
if (closeCode1 !== -1) {
|
|
673
677
|
if (xmlData.charCodeAt(index + 1) === closeCode1) {
|
|
674
|
-
|
|
678
|
+
result += xmlData.substring(segmentStart, index);
|
|
679
|
+
return { data: result, index };
|
|
675
680
|
}
|
|
676
681
|
} else {
|
|
677
|
-
|
|
682
|
+
result += xmlData.substring(segmentStart, index);
|
|
683
|
+
return { data: result, index };
|
|
678
684
|
}
|
|
679
|
-
} else if (code === 9) { // \t
|
|
680
|
-
|
|
681
|
-
|
|
685
|
+
} else if (code === 9 && !attrBoundary) { // \t - only replace with space outside attribute values
|
|
686
|
+
// Flush accumulated segment, add space, start new segment
|
|
687
|
+
result += xmlData.substring(segmentStart, index) + ' ';
|
|
688
|
+
segmentStart = index + 1;
|
|
682
689
|
}
|
|
683
|
-
|
|
684
|
-
chars.push(code);
|
|
685
690
|
}
|
|
686
691
|
}
|
|
687
692
|
|
|
@@ -771,7 +776,7 @@ function readStopNodeData(xmlData, tagName, i) {
|
|
|
771
776
|
const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
|
|
772
777
|
i = closeIndex;
|
|
773
778
|
} else {
|
|
774
|
-
const tagData = readTagExp(xmlData, i,
|
|
779
|
+
const tagData = readTagExp(xmlData, i, false)
|
|
775
780
|
|
|
776
781
|
if (tagData) {
|
|
777
782
|
const openTagName = tagData && tagData.tagName;
|
|
@@ -31,8 +31,8 @@ export default class XMLParser {
|
|
|
31
31
|
throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
const orderedObjParser = new OrderedObjParser(this.options);
|
|
35
|
-
orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities);
|
|
34
|
+
const orderedObjParser = new OrderedObjParser(this.options, this.externalEntities);
|
|
35
|
+
// orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities);
|
|
36
36
|
const orderedResult = orderedObjParser.parseXml(xmlData);
|
|
37
37
|
if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;
|
|
38
38
|
else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);
|
|
@@ -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) {
|