@jjrawlins/cdk-diff-pr-github-action 1.9.13 → 1.9.14
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/.jsii +3 -3
- package/cdkdiffprgithubaction/jsii/jsii.go +2 -2
- package/cdkdiffprgithubaction/version +1 -1
- package/lib/CdkDiffIamTemplate.js +2 -2
- package/lib/CdkDiffIamTemplateStackSet.js +2 -2
- package/lib/CdkDiffStackWorkflow.js +1 -1
- package/lib/CdkDriftDetectionWorkflow.js +1 -1
- package/lib/CdkDriftIamTemplate.js +2 -2
- package/node_modules/@aws-sdk/client-cloudformation/package.json +13 -13
- package/node_modules/@aws-sdk/core/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-env/package.json +2 -2
- package/node_modules/@aws-sdk/credential-provider-http/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-ini/package.json +9 -9
- package/node_modules/@aws-sdk/credential-provider-login/package.json +3 -3
- package/node_modules/@aws-sdk/credential-provider-node/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-process/package.json +2 -2
- package/node_modules/@aws-sdk/credential-provider-sso/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +3 -3
- package/node_modules/@aws-sdk/middleware-user-agent/package.json +3 -3
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/cognito-identity/CognitoIdentity.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-types/submodules/cognito-identity/CognitoIdentity.d.ts +2 -2
- package/node_modules/@aws-sdk/nested-clients/package.json +12 -12
- package/node_modules/@aws-sdk/token-providers/package.json +3 -3
- package/node_modules/@aws-sdk/util-user-agent-node/package.json +2 -2
- package/node_modules/@aws-sdk/xml-builder/package.json +2 -2
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/CHANGELOG.md +33 -4
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/README.md +8 -7
- package/node_modules/fast-xml-parser/lib/fxbuilder.min.js +2 -0
- package/node_modules/fast-xml-parser/lib/fxbuilder.min.js.map +1 -0
- package/node_modules/fast-xml-parser/lib/fxp.cjs +1 -0
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxp.d.cts +73 -19
- package/node_modules/fast-xml-parser/lib/fxp.min.js +2 -0
- package/node_modules/fast-xml-parser/lib/fxp.min.js.map +1 -0
- package/node_modules/fast-xml-parser/lib/fxparser.min.js +2 -0
- package/node_modules/fast-xml-parser/lib/fxparser.min.js.map +1 -0
- package/node_modules/fast-xml-parser/lib/fxvalidator.min.js.map +1 -0
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/package.json +3 -2
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/fxp.d.ts +73 -19
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/util.js +18 -0
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/DocTypeReader.js +12 -2
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/OptionsBuilder.js +71 -0
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/OrderedObjParser.js +291 -115
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/XMLParser.js +1 -1
- package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/node2json.js +65 -14
- package/package.json +2 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxbuilder.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxbuilder.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.cjs +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxp.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxparser.min.js +0 -2
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxparser.min.js.map +0 -1
- package/node_modules/@aws-sdk/xml-builder/node_modules/fast-xml-parser/lib/fxvalidator.min.js.map +0 -1
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/LICENSE +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/lib/fxvalidator.min.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/cli/cli.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/cli/man.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/cli/read.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/fxp.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/ignoreAttributes.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/CharsSymbol.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/EntitiesParser.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OptionsBuilder.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/BaseOutputBuilder.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/JsArrBuilder.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/JsMinArrBuilder.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/JsObjBuilder.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/OutputBuilders/ParserOptionsBuilder.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/Report.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/TagPath.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/TagPathMatcher.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/XMLParser.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/Xml2JsParser.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/XmlPartReader.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/XmlSpecialTagsReader.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/inputSource/BufferSource.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/inputSource/StringSource.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/EntitiesParser.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/booleanParser.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/booleanParserExt.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/currency.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/join.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/number.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/v6/valueParsers/trim.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/validator.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlbuilder/json2xml.js +0 -0
- /package/node_modules/{@aws-sdk/xml-builder/node_modules/fast-xml-parser → fast-xml-parser}/src/xmlparser/xmlNode.js +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
///@ts-check
|
|
3
3
|
|
|
4
|
-
import { getAllMatches, isExist } from '../util.js';
|
|
4
|
+
import { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';
|
|
5
5
|
import xmlNode from './xmlNode.js';
|
|
6
6
|
import DocTypeReader from './DocTypeReader.js';
|
|
7
7
|
import toNumber from "strnum";
|
|
8
8
|
import getIgnoreAttributesFn from "../ignoreAttributes.js";
|
|
9
|
+
import { Expression, Matcher } from 'path-expression-matcher';
|
|
9
10
|
|
|
10
11
|
// const regx =
|
|
11
12
|
// '<((!\\[CDATA\\[([\\s\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\/)(NAME)\\s*>))([^<]*)'
|
|
@@ -14,6 +15,57 @@ import getIgnoreAttributesFn from "../ignoreAttributes.js";
|
|
|
14
15
|
//const tagsRegx = new RegExp("<(\\/?[\\w:\\-\._]+)([^>]*)>(\\s*"+cdataRegx+")*([^<]+)?","g");
|
|
15
16
|
//const tagsRegx = new RegExp("<(\\/?)((\\w*:)?([\\w:\\-\._]+))([^>]*)>([^<]*)("+cdataRegx+"([^<]*))*([^<]+)?","g");
|
|
16
17
|
|
|
18
|
+
// Helper functions for attribute and namespace handling
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Extract raw attributes (without prefix) from prefixed attribute map
|
|
22
|
+
* @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap
|
|
23
|
+
* @param {object} options - Parser options containing attributeNamePrefix
|
|
24
|
+
* @returns {object} Raw attributes for matcher
|
|
25
|
+
*/
|
|
26
|
+
function extractRawAttributes(prefixedAttrs, options) {
|
|
27
|
+
if (!prefixedAttrs) return {};
|
|
28
|
+
|
|
29
|
+
// Handle attributesGroupName option
|
|
30
|
+
const attrs = options.attributesGroupName
|
|
31
|
+
? prefixedAttrs[options.attributesGroupName]
|
|
32
|
+
: prefixedAttrs;
|
|
33
|
+
|
|
34
|
+
if (!attrs) return {};
|
|
35
|
+
|
|
36
|
+
const rawAttrs = {};
|
|
37
|
+
for (const key in attrs) {
|
|
38
|
+
// Remove the attribute prefix to get raw name
|
|
39
|
+
if (key.startsWith(options.attributeNamePrefix)) {
|
|
40
|
+
const rawName = key.substring(options.attributeNamePrefix.length);
|
|
41
|
+
rawAttrs[rawName] = attrs[key];
|
|
42
|
+
} else {
|
|
43
|
+
// Attribute without prefix (shouldn't normally happen, but be safe)
|
|
44
|
+
rawAttrs[key] = attrs[key];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return rawAttrs;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Extract namespace from raw tag name
|
|
52
|
+
* @param {string} rawTagName - Tag name possibly with namespace (e.g., "soap:Envelope")
|
|
53
|
+
* @returns {string|undefined} Namespace or undefined
|
|
54
|
+
*/
|
|
55
|
+
function extractNamespace(rawTagName) {
|
|
56
|
+
if (!rawTagName || typeof rawTagName !== 'string') return undefined;
|
|
57
|
+
|
|
58
|
+
const colonIndex = rawTagName.indexOf(':');
|
|
59
|
+
if (colonIndex !== -1 && colonIndex > 0) {
|
|
60
|
+
const ns = rawTagName.substring(0, colonIndex);
|
|
61
|
+
// Don't treat xmlns as a namespace
|
|
62
|
+
if (ns !== 'xmlns') {
|
|
63
|
+
return ns;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
17
69
|
export default class OrderedObjParser {
|
|
18
70
|
constructor(options) {
|
|
19
71
|
this.options = options;
|
|
@@ -58,16 +110,23 @@ export default class OrderedObjParser {
|
|
|
58
110
|
this.entityExpansionCount = 0;
|
|
59
111
|
this.currentExpandedLength = 0;
|
|
60
112
|
|
|
113
|
+
// Initialize path matcher for path-expression-matcher
|
|
114
|
+
this.matcher = new Matcher();
|
|
115
|
+
|
|
116
|
+
// Flag to track if current node is a stop node (optimization)
|
|
117
|
+
this.isCurrentNodeStopNode = false;
|
|
118
|
+
|
|
119
|
+
// Pre-compile stopNodes expressions
|
|
61
120
|
if (this.options.stopNodes && this.options.stopNodes.length > 0) {
|
|
62
|
-
this.
|
|
63
|
-
this.stopNodesWildcard = new Set();
|
|
121
|
+
this.stopNodeExpressions = [];
|
|
64
122
|
for (let i = 0; i < this.options.stopNodes.length; i++) {
|
|
65
123
|
const stopNodeExp = this.options.stopNodes[i];
|
|
66
|
-
if (typeof stopNodeExp
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
} else {
|
|
70
|
-
|
|
124
|
+
if (typeof stopNodeExp === 'string') {
|
|
125
|
+
// Convert string to Expression object
|
|
126
|
+
this.stopNodeExpressions.push(new Expression(stopNodeExp));
|
|
127
|
+
} else if (stopNodeExp instanceof Expression) {
|
|
128
|
+
// Already an Expression object
|
|
129
|
+
this.stopNodeExpressions.push(stopNodeExp);
|
|
71
130
|
}
|
|
72
131
|
}
|
|
73
132
|
}
|
|
@@ -90,7 +149,7 @@ function addExternalEntities(externalEntities) {
|
|
|
90
149
|
/**
|
|
91
150
|
* @param {string} val
|
|
92
151
|
* @param {string} tagName
|
|
93
|
-
* @param {string} jPath
|
|
152
|
+
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
|
|
94
153
|
* @param {boolean} dontTrim
|
|
95
154
|
* @param {boolean} hasAttributes
|
|
96
155
|
* @param {boolean} isLeafNode
|
|
@@ -104,7 +163,9 @@ function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode,
|
|
|
104
163
|
if (val.length > 0) {
|
|
105
164
|
if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);
|
|
106
165
|
|
|
107
|
-
|
|
166
|
+
// Pass jPath string or matcher based on options.jPath setting
|
|
167
|
+
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
168
|
+
const newval = this.options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);
|
|
108
169
|
if (newval === null || newval === undefined) {
|
|
109
170
|
//don't parse
|
|
110
171
|
return val;
|
|
@@ -151,25 +212,58 @@ function buildAttributesMap(attrStr, jPath, tagName) {
|
|
|
151
212
|
const matches = getAllMatches(attrStr, attrsRegx);
|
|
152
213
|
const len = matches.length; //don't make it inline
|
|
153
214
|
const attrs = {};
|
|
215
|
+
|
|
216
|
+
// First pass: parse all attributes and update matcher with raw values
|
|
217
|
+
// This ensures the matcher has all attribute values when processors run
|
|
218
|
+
const rawAttrsForMatcher = {};
|
|
154
219
|
for (let i = 0; i < len; i++) {
|
|
155
220
|
const attrName = this.resolveNameSpace(matches[i][1]);
|
|
156
|
-
|
|
221
|
+
const oldVal = matches[i][4];
|
|
222
|
+
|
|
223
|
+
if (attrName.length && oldVal !== undefined) {
|
|
224
|
+
let parsedVal = oldVal;
|
|
225
|
+
if (this.options.trimValues) {
|
|
226
|
+
parsedVal = parsedVal.trim();
|
|
227
|
+
}
|
|
228
|
+
parsedVal = this.replaceEntitiesValue(parsedVal, tagName, jPath);
|
|
229
|
+
rawAttrsForMatcher[attrName] = parsedVal;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Update matcher with raw attribute values BEFORE running processors
|
|
234
|
+
if (Object.keys(rawAttrsForMatcher).length > 0 && typeof jPath === 'object' && jPath.updateCurrent) {
|
|
235
|
+
jPath.updateCurrent(rawAttrsForMatcher);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Second pass: now process attributes with matcher having full attribute context
|
|
239
|
+
for (let i = 0; i < len; i++) {
|
|
240
|
+
const attrName = this.resolveNameSpace(matches[i][1]);
|
|
241
|
+
|
|
242
|
+
// Convert jPath to string if needed for ignoreAttributesFn
|
|
243
|
+
const jPathStr = this.options.jPath ? jPath.toString() : jPath;
|
|
244
|
+
if (this.ignoreAttributesFn(attrName, jPathStr)) {
|
|
157
245
|
continue
|
|
158
246
|
}
|
|
247
|
+
|
|
159
248
|
let oldVal = matches[i][4];
|
|
160
249
|
let aName = this.options.attributeNamePrefix + attrName;
|
|
250
|
+
|
|
161
251
|
if (attrName.length) {
|
|
162
252
|
if (this.options.transformAttributeName) {
|
|
163
253
|
aName = this.options.transformAttributeName(aName);
|
|
164
254
|
}
|
|
165
|
-
if (aName === "__proto__") aName = "#__proto__";
|
|
255
|
+
//if (aName === "__proto__") aName = "#__proto__";
|
|
256
|
+
aName = sanitizeName(aName, this.options);
|
|
166
257
|
|
|
167
258
|
if (oldVal !== undefined) {
|
|
168
259
|
if (this.options.trimValues) {
|
|
169
260
|
oldVal = oldVal.trim();
|
|
170
261
|
}
|
|
171
262
|
oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath);
|
|
172
|
-
|
|
263
|
+
|
|
264
|
+
// Pass jPath string or matcher based on options.jPath setting
|
|
265
|
+
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
266
|
+
const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPathOrMatcher);
|
|
173
267
|
if (newVal === null || newVal === undefined) {
|
|
174
268
|
//don't parse
|
|
175
269
|
attrs[aName] = oldVal;
|
|
@@ -189,6 +283,7 @@ function buildAttributesMap(attrStr, jPath, tagName) {
|
|
|
189
283
|
}
|
|
190
284
|
}
|
|
191
285
|
}
|
|
286
|
+
|
|
192
287
|
if (!Object.keys(attrs).length) {
|
|
193
288
|
return;
|
|
194
289
|
}
|
|
@@ -206,7 +301,9 @@ const parseXml = function (xmlData) {
|
|
|
206
301
|
const xmlObj = new xmlNode('!xml');
|
|
207
302
|
let currentNode = xmlObj;
|
|
208
303
|
let textData = "";
|
|
209
|
-
|
|
304
|
+
|
|
305
|
+
// Reset matcher for new document
|
|
306
|
+
this.matcher.reset();
|
|
210
307
|
|
|
211
308
|
// Reset entity expansion counters for this document
|
|
212
309
|
this.entityExpansionCount = 0;
|
|
@@ -229,27 +326,25 @@ const parseXml = function (xmlData) {
|
|
|
229
326
|
}
|
|
230
327
|
}
|
|
231
328
|
|
|
232
|
-
|
|
233
|
-
tagName = this.options.transformTagName(tagName);
|
|
234
|
-
}
|
|
329
|
+
tagName = transformTagName(this.options.transformTagName, tagName, "", this.options).tagName;
|
|
235
330
|
|
|
236
331
|
if (currentNode) {
|
|
237
|
-
textData = this.saveTextToParentTag(textData, currentNode,
|
|
332
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.matcher);
|
|
238
333
|
}
|
|
239
334
|
|
|
240
335
|
//check if last tag of nested tag was unpaired tag
|
|
241
|
-
const lastTagName =
|
|
336
|
+
const lastTagName = this.matcher.getCurrentTag();
|
|
242
337
|
if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) {
|
|
243
338
|
throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
|
|
244
339
|
}
|
|
245
|
-
let propIndex = 0
|
|
246
340
|
if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) {
|
|
247
|
-
|
|
341
|
+
// Pop the unpaired tag
|
|
342
|
+
this.matcher.pop();
|
|
248
343
|
this.tagsNodeStack.pop();
|
|
249
|
-
} else {
|
|
250
|
-
propIndex = jPath.lastIndexOf(".");
|
|
251
344
|
}
|
|
252
|
-
|
|
345
|
+
// Pop the closing tag
|
|
346
|
+
this.matcher.pop();
|
|
347
|
+
this.isCurrentNodeStopNode = false; // Reset flag when closing tag
|
|
253
348
|
|
|
254
349
|
currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope
|
|
255
350
|
textData = "";
|
|
@@ -259,7 +354,7 @@ const parseXml = function (xmlData) {
|
|
|
259
354
|
let tagData = readTagExp(xmlData, i, false, "?>");
|
|
260
355
|
if (!tagData) throw new Error("Pi Tag is not closed.");
|
|
261
356
|
|
|
262
|
-
textData = this.saveTextToParentTag(textData, currentNode,
|
|
357
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.matcher);
|
|
263
358
|
if ((this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags) {
|
|
264
359
|
//do nothing
|
|
265
360
|
} else {
|
|
@@ -268,9 +363,9 @@ const parseXml = function (xmlData) {
|
|
|
268
363
|
childNode.add(this.options.textNodeName, "");
|
|
269
364
|
|
|
270
365
|
if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) {
|
|
271
|
-
childNode[":@"] = this.buildAttributesMap(tagData.tagExp,
|
|
366
|
+
childNode[":@"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName);
|
|
272
367
|
}
|
|
273
|
-
this.addChild(currentNode, childNode,
|
|
368
|
+
this.addChild(currentNode, childNode, this.matcher, i);
|
|
274
369
|
}
|
|
275
370
|
|
|
276
371
|
|
|
@@ -280,7 +375,7 @@ const parseXml = function (xmlData) {
|
|
|
280
375
|
if (this.options.commentPropName) {
|
|
281
376
|
const comment = xmlData.substring(i + 4, endIndex - 2);
|
|
282
377
|
|
|
283
|
-
textData = this.saveTextToParentTag(textData, currentNode,
|
|
378
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.matcher);
|
|
284
379
|
|
|
285
380
|
currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]);
|
|
286
381
|
}
|
|
@@ -293,9 +388,9 @@ const parseXml = function (xmlData) {
|
|
|
293
388
|
const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
|
|
294
389
|
const tagExp = xmlData.substring(i + 9, closeIndex);
|
|
295
390
|
|
|
296
|
-
textData = this.saveTextToParentTag(textData, currentNode,
|
|
391
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.matcher);
|
|
297
392
|
|
|
298
|
-
let val = this.parseTextData(tagExp, currentNode.tagname,
|
|
393
|
+
let val = this.parseTextData(tagExp, currentNode.tagname, this.matcher, true, false, true, true);
|
|
299
394
|
if (val == undefined) val = "";
|
|
300
395
|
|
|
301
396
|
//cdata should be set even if it is 0 length string
|
|
@@ -308,20 +403,21 @@ const parseXml = function (xmlData) {
|
|
|
308
403
|
i = closeIndex + 2;
|
|
309
404
|
} else {//Opening tag
|
|
310
405
|
let result = readTagExp(xmlData, i, this.options.removeNSPrefix);
|
|
406
|
+
|
|
407
|
+
// Safety check: readTagExp can return undefined
|
|
408
|
+
if (!result) {
|
|
409
|
+
// Log context for debugging
|
|
410
|
+
const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlData.length, i + 50));
|
|
411
|
+
throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context}"`);
|
|
412
|
+
}
|
|
413
|
+
|
|
311
414
|
let tagName = result.tagName;
|
|
312
415
|
const rawTagName = result.rawTagName;
|
|
313
416
|
let tagExp = result.tagExp;
|
|
314
417
|
let attrExpPresent = result.attrExpPresent;
|
|
315
418
|
let closeIndex = result.closeIndex;
|
|
316
419
|
|
|
317
|
-
|
|
318
|
-
//console.log(tagExp, tagName)
|
|
319
|
-
const newTagName = this.options.transformTagName(tagName);
|
|
320
|
-
if (tagExp === tagName) {
|
|
321
|
-
tagExp = newTagName
|
|
322
|
-
}
|
|
323
|
-
tagName = newTagName;
|
|
324
|
-
}
|
|
420
|
+
({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));
|
|
325
421
|
|
|
326
422
|
if (this.options.strictReservedNames &&
|
|
327
423
|
(tagName === this.options.commentPropName
|
|
@@ -334,7 +430,7 @@ const parseXml = function (xmlData) {
|
|
|
334
430
|
if (currentNode && textData) {
|
|
335
431
|
if (currentNode.tagname !== '!xml') {
|
|
336
432
|
//when nested tag is found
|
|
337
|
-
textData = this.saveTextToParentTag(textData, currentNode,
|
|
433
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.matcher, false);
|
|
338
434
|
}
|
|
339
435
|
}
|
|
340
436
|
|
|
@@ -342,28 +438,65 @@ const parseXml = function (xmlData) {
|
|
|
342
438
|
const lastTag = currentNode;
|
|
343
439
|
if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) {
|
|
344
440
|
currentNode = this.tagsNodeStack.pop();
|
|
345
|
-
|
|
441
|
+
this.matcher.pop();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Clean up self-closing syntax BEFORE processing attributes
|
|
445
|
+
// This is where tagExp gets the trailing / removed
|
|
446
|
+
let isSelfClosing = false;
|
|
447
|
+
if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
|
|
448
|
+
isSelfClosing = true;
|
|
449
|
+
if (tagName[tagName.length - 1] === "/") {
|
|
450
|
+
tagName = tagName.substr(0, tagName.length - 1);
|
|
451
|
+
tagExp = tagName;
|
|
452
|
+
} else {
|
|
453
|
+
tagExp = tagExp.substr(0, tagExp.length - 1);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Re-check attrExpPresent after cleaning
|
|
457
|
+
attrExpPresent = (tagName !== tagExp);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Now process attributes with CLEAN tagExp (no trailing /)
|
|
461
|
+
let prefixedAttrs = null;
|
|
462
|
+
let rawAttrs = {};
|
|
463
|
+
let namespace = undefined;
|
|
464
|
+
|
|
465
|
+
// Extract namespace from rawTagName
|
|
466
|
+
namespace = extractNamespace(rawTagName);
|
|
467
|
+
|
|
468
|
+
// Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path
|
|
469
|
+
if (tagName !== xmlObj.tagname) {
|
|
470
|
+
this.matcher.push(tagName, {}, namespace);
|
|
346
471
|
}
|
|
472
|
+
|
|
473
|
+
// Now build attributes - callbacks will see correct matcher state
|
|
474
|
+
if (tagName !== tagExp && attrExpPresent) {
|
|
475
|
+
// Build attributes (returns prefixed attributes for the tree)
|
|
476
|
+
// Note: buildAttributesMap now internally updates the matcher with raw attributes
|
|
477
|
+
prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);
|
|
478
|
+
|
|
479
|
+
if (prefixedAttrs) {
|
|
480
|
+
// Extract raw attributes (without prefix) for our use
|
|
481
|
+
rawAttrs = extractRawAttributes(prefixedAttrs, this.options);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Now check if this is a stop node (after attributes are set)
|
|
347
486
|
if (tagName !== xmlObj.tagname) {
|
|
348
|
-
|
|
487
|
+
this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher);
|
|
349
488
|
}
|
|
489
|
+
|
|
350
490
|
const startIndex = i;
|
|
351
|
-
if (this.
|
|
491
|
+
if (this.isCurrentNodeStopNode) {
|
|
352
492
|
let tagContent = "";
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
tagName = tagName.substr(0, tagName.length - 1);
|
|
357
|
-
jPath = jPath.substr(0, jPath.length - 1);
|
|
358
|
-
tagExp = tagName;
|
|
359
|
-
} else {
|
|
360
|
-
tagExp = tagExp.substr(0, tagExp.length - 1);
|
|
361
|
-
}
|
|
493
|
+
|
|
494
|
+
// For self-closing tags, content is empty
|
|
495
|
+
if (isSelfClosing) {
|
|
362
496
|
i = result.closeIndex;
|
|
363
497
|
}
|
|
364
498
|
//unpaired tag
|
|
365
499
|
else if (this.options.unpairedTags.indexOf(tagName) !== -1) {
|
|
366
|
-
|
|
367
500
|
i = result.closeIndex;
|
|
368
501
|
}
|
|
369
502
|
//normal tag
|
|
@@ -377,50 +510,38 @@ const parseXml = function (xmlData) {
|
|
|
377
510
|
|
|
378
511
|
const childNode = new xmlNode(tagName);
|
|
379
512
|
|
|
380
|
-
if (
|
|
381
|
-
childNode[":@"] =
|
|
382
|
-
}
|
|
383
|
-
if (tagContent) {
|
|
384
|
-
tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
|
|
513
|
+
if (prefixedAttrs) {
|
|
514
|
+
childNode[":@"] = prefixedAttrs;
|
|
385
515
|
}
|
|
386
516
|
|
|
387
|
-
|
|
517
|
+
// For stop nodes, store raw content as-is without any processing
|
|
388
518
|
childNode.add(this.options.textNodeName, tagContent);
|
|
389
519
|
|
|
390
|
-
this.
|
|
520
|
+
this.matcher.pop(); // Pop the stop node tag
|
|
521
|
+
this.isCurrentNodeStopNode = false; // Reset flag
|
|
522
|
+
|
|
523
|
+
this.addChild(currentNode, childNode, this.matcher, startIndex);
|
|
391
524
|
} else {
|
|
392
525
|
//selfClosing tag
|
|
393
|
-
if (
|
|
394
|
-
|
|
395
|
-
tagName = tagName.substr(0, tagName.length - 1);
|
|
396
|
-
jPath = jPath.substr(0, jPath.length - 1);
|
|
397
|
-
tagExp = tagName;
|
|
398
|
-
} else {
|
|
399
|
-
tagExp = tagExp.substr(0, tagExp.length - 1);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
if (this.options.transformTagName) {
|
|
403
|
-
const newTagName = this.options.transformTagName(tagName);
|
|
404
|
-
if (tagExp === tagName) {
|
|
405
|
-
tagExp = newTagName
|
|
406
|
-
}
|
|
407
|
-
tagName = newTagName;
|
|
408
|
-
}
|
|
526
|
+
if (isSelfClosing) {
|
|
527
|
+
({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));
|
|
409
528
|
|
|
410
529
|
const childNode = new xmlNode(tagName);
|
|
411
|
-
if (
|
|
412
|
-
childNode[":@"] =
|
|
530
|
+
if (prefixedAttrs) {
|
|
531
|
+
childNode[":@"] = prefixedAttrs;
|
|
413
532
|
}
|
|
414
|
-
this.addChild(currentNode, childNode,
|
|
415
|
-
|
|
533
|
+
this.addChild(currentNode, childNode, this.matcher, startIndex);
|
|
534
|
+
this.matcher.pop(); // Pop self-closing tag
|
|
535
|
+
this.isCurrentNodeStopNode = false; // Reset flag
|
|
416
536
|
}
|
|
417
|
-
else if(this.options.unpairedTags.indexOf(tagName) !== -1){//unpaired tag
|
|
537
|
+
else if (this.options.unpairedTags.indexOf(tagName) !== -1) {//unpaired tag
|
|
418
538
|
const childNode = new xmlNode(tagName);
|
|
419
|
-
if(
|
|
420
|
-
childNode[":@"] =
|
|
539
|
+
if (prefixedAttrs) {
|
|
540
|
+
childNode[":@"] = prefixedAttrs;
|
|
421
541
|
}
|
|
422
|
-
this.addChild(currentNode, childNode,
|
|
423
|
-
|
|
542
|
+
this.addChild(currentNode, childNode, this.matcher, startIndex);
|
|
543
|
+
this.matcher.pop(); // Pop unpaired tag
|
|
544
|
+
this.isCurrentNodeStopNode = false; // Reset flag
|
|
424
545
|
i = result.closeIndex;
|
|
425
546
|
// Continue to next iteration without changing currentNode
|
|
426
547
|
continue;
|
|
@@ -433,10 +554,10 @@ const parseXml = function (xmlData) {
|
|
|
433
554
|
}
|
|
434
555
|
this.tagsNodeStack.push(currentNode);
|
|
435
556
|
|
|
436
|
-
if (
|
|
437
|
-
childNode[":@"] =
|
|
557
|
+
if (prefixedAttrs) {
|
|
558
|
+
childNode[":@"] = prefixedAttrs;
|
|
438
559
|
}
|
|
439
|
-
this.addChild(currentNode, childNode,
|
|
560
|
+
this.addChild(currentNode, childNode, this.matcher, startIndex);
|
|
440
561
|
currentNode = childNode;
|
|
441
562
|
}
|
|
442
563
|
textData = "";
|
|
@@ -450,10 +571,13 @@ const parseXml = function (xmlData) {
|
|
|
450
571
|
return xmlObj.child;
|
|
451
572
|
}
|
|
452
573
|
|
|
453
|
-
function addChild(currentNode, childNode,
|
|
574
|
+
function addChild(currentNode, childNode, matcher, startIndex) {
|
|
454
575
|
// unset startIndex if not requested
|
|
455
576
|
if (!this.options.captureMetaData) startIndex = undefined;
|
|
456
|
-
|
|
577
|
+
|
|
578
|
+
// Pass jPath string or matcher based on options.jPath setting
|
|
579
|
+
const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;
|
|
580
|
+
const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[":@"])
|
|
457
581
|
if (result === false) {
|
|
458
582
|
//do nothing
|
|
459
583
|
} else if (typeof result === "string") {
|
|
@@ -464,33 +588,40 @@ function addChild(currentNode, childNode, jPath, startIndex) {
|
|
|
464
588
|
}
|
|
465
589
|
}
|
|
466
590
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
591
|
+
/**
|
|
592
|
+
* @param {object} val - Entity object with regex and val properties
|
|
593
|
+
* @param {string} tagName - Tag name
|
|
594
|
+
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
|
|
595
|
+
*/
|
|
596
|
+
function replaceEntitiesValue(val, tagName, jPath) {
|
|
473
597
|
const entityConfig = this.options.processEntities;
|
|
474
598
|
|
|
475
|
-
if (!entityConfig.enabled) {
|
|
599
|
+
if (!entityConfig || !entityConfig.enabled) {
|
|
476
600
|
return val;
|
|
477
601
|
}
|
|
478
602
|
|
|
479
|
-
// Check tag
|
|
603
|
+
// Check if tag is allowed to contain entities
|
|
480
604
|
if (entityConfig.allowedTags) {
|
|
481
|
-
|
|
482
|
-
|
|
605
|
+
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
606
|
+
const allowed = Array.isArray(entityConfig.allowedTags)
|
|
607
|
+
? entityConfig.allowedTags.includes(tagName)
|
|
608
|
+
: entityConfig.allowedTags(tagName, jPathOrMatcher);
|
|
609
|
+
|
|
610
|
+
if (!allowed) {
|
|
611
|
+
return val;
|
|
483
612
|
}
|
|
484
613
|
}
|
|
485
614
|
|
|
615
|
+
// Apply custom tag filter if provided
|
|
486
616
|
if (entityConfig.tagFilter) {
|
|
487
|
-
|
|
617
|
+
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
618
|
+
if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {
|
|
488
619
|
return val; // Skip based on custom filter
|
|
489
620
|
}
|
|
490
621
|
}
|
|
491
622
|
|
|
492
623
|
// Replace DOCTYPE entities
|
|
493
|
-
for (
|
|
624
|
+
for (const entityName of Object.keys(this.docTypeEntities)) {
|
|
494
625
|
const entity = this.docTypeEntities[entityName];
|
|
495
626
|
const matches = val.match(entity.regx);
|
|
496
627
|
|
|
@@ -522,19 +653,38 @@ const replaceEntitiesValue = function (val, tagName, jPath) {
|
|
|
522
653
|
}
|
|
523
654
|
}
|
|
524
655
|
}
|
|
525
|
-
if (val.indexOf('&') === -1) return val; // Early exit
|
|
526
|
-
|
|
527
656
|
// Replace standard entities
|
|
528
|
-
for (
|
|
657
|
+
for (const entityName of Object.keys(this.lastEntities)) {
|
|
529
658
|
const entity = this.lastEntities[entityName];
|
|
659
|
+
const matches = val.match(entity.regex);
|
|
660
|
+
if (matches) {
|
|
661
|
+
this.entityExpansionCount += matches.length;
|
|
662
|
+
if (entityConfig.maxTotalExpansions &&
|
|
663
|
+
this.entityExpansionCount > entityConfig.maxTotalExpansions) {
|
|
664
|
+
throw new Error(
|
|
665
|
+
`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
530
669
|
val = val.replace(entity.regex, entity.val);
|
|
531
670
|
}
|
|
532
|
-
if (val.indexOf('&') === -1) return val;
|
|
671
|
+
if (val.indexOf('&') === -1) return val;
|
|
533
672
|
|
|
534
673
|
// Replace HTML entities if enabled
|
|
535
674
|
if (this.options.htmlEntities) {
|
|
536
|
-
for (
|
|
675
|
+
for (const entityName of Object.keys(this.htmlEntities)) {
|
|
537
676
|
const entity = this.htmlEntities[entityName];
|
|
677
|
+
const matches = val.match(entity.regex);
|
|
678
|
+
if (matches) {
|
|
679
|
+
//console.log(matches);
|
|
680
|
+
this.entityExpansionCount += matches.length;
|
|
681
|
+
if (entityConfig.maxTotalExpansions &&
|
|
682
|
+
this.entityExpansionCount > entityConfig.maxTotalExpansions) {
|
|
683
|
+
throw new Error(
|
|
684
|
+
`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
538
688
|
val = val.replace(entity.regex, entity.val);
|
|
539
689
|
}
|
|
540
690
|
}
|
|
@@ -546,13 +696,13 @@ const replaceEntitiesValue = function (val, tagName, jPath) {
|
|
|
546
696
|
}
|
|
547
697
|
|
|
548
698
|
|
|
549
|
-
function saveTextToParentTag(textData, parentNode,
|
|
699
|
+
function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {
|
|
550
700
|
if (textData) { //store previously collected data as textNode
|
|
551
701
|
if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0
|
|
552
702
|
|
|
553
703
|
textData = this.parseTextData(textData,
|
|
554
704
|
parentNode.tagname,
|
|
555
|
-
|
|
705
|
+
matcher,
|
|
556
706
|
false,
|
|
557
707
|
parentNode[":@"] ? Object.keys(parentNode[":@"]).length !== 0 : false,
|
|
558
708
|
isLeafNode);
|
|
@@ -566,14 +716,17 @@ function saveTextToParentTag(textData, parentNode, jPath, isLeafNode) {
|
|
|
566
716
|
|
|
567
717
|
//TODO: use jPath to simplify the logic
|
|
568
718
|
/**
|
|
569
|
-
* @param {
|
|
570
|
-
* @param {
|
|
571
|
-
* @param {string} jPath
|
|
572
|
-
* @param {string} currentTagName
|
|
719
|
+
* @param {Array<Expression>} stopNodeExpressions - Array of compiled Expression objects
|
|
720
|
+
* @param {Matcher} matcher - Current path matcher
|
|
573
721
|
*/
|
|
574
|
-
function isItStopNode(
|
|
575
|
-
if (
|
|
576
|
-
|
|
722
|
+
function isItStopNode(stopNodeExpressions, matcher) {
|
|
723
|
+
if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;
|
|
724
|
+
|
|
725
|
+
for (let i = 0; i < stopNodeExpressions.length; i++) {
|
|
726
|
+
if (matcher.matches(stopNodeExpressions[i])) {
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
577
730
|
return false;
|
|
578
731
|
}
|
|
579
732
|
|
|
@@ -726,4 +879,27 @@ function fromCodePoint(str, base, prefix) {
|
|
|
726
879
|
} else {
|
|
727
880
|
return prefix + str + ";";
|
|
728
881
|
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
function transformTagName(fn, tagName, tagExp, options) {
|
|
885
|
+
if (fn) {
|
|
886
|
+
const newTagName = fn(tagName);
|
|
887
|
+
if (tagExp === tagName) {
|
|
888
|
+
tagExp = newTagName
|
|
889
|
+
}
|
|
890
|
+
tagName = newTagName;
|
|
891
|
+
}
|
|
892
|
+
tagName = sanitizeName(tagName, options);
|
|
893
|
+
return { tagName, tagExp };
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
function sanitizeName(name, options) {
|
|
899
|
+
if (criticalProperties.includes(name)) {
|
|
900
|
+
throw new Error(`[SECURITY] Invalid name: "${name}" is a reserved JavaScript keyword that could cause prototype pollution`);
|
|
901
|
+
} else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {
|
|
902
|
+
return options.onDangerousProperty(name);
|
|
903
|
+
}
|
|
904
|
+
return name;
|
|
729
905
|
}
|
|
@@ -35,7 +35,7 @@ export default class XMLParser {
|
|
|
35
35
|
orderedObjParser.addExternalEntities(this.externalEntities);
|
|
36
36
|
const orderedResult = orderedObjParser.parseXml(xmlData);
|
|
37
37
|
if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;
|
|
38
|
-
else return prettify(orderedResult, this.options);
|
|
38
|
+
else return prettify(orderedResult, this.options, orderedObjParser.matcher);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|