xml-disassembler 1.10.2 → 1.10.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 +14 -0
- package/disassemble.log +506 -558
- package/dist/index.cjs +171 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.cjs.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.min.umd.js +1 -1
- package/dist/index.min.umd.js.map +1 -1
- package/dist/index.mjs +173 -159
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +171 -157
- package/dist/index.umd.js.map +1 -1
- package/dist/typings/builders/buildLeafFile.d.ts +2 -1
- package/dist/typings/builders/strategies/grouped-by-tag/buildDisassembledFiles.d.ts +1 -1
- package/dist/typings/builders/strategies/uid/buildDisassembledFiles.d.ts +1 -1
- package/dist/typings/handlers/reassembleXMLFileHandler.d.ts +1 -1
- package/dist/typings/parsers/strategies/grouped-by-tag/parseElement.d.ts +1 -1
- package/dist/typings/parsers/strategies/uid/parseElement.d.ts +2 -2
- package/dist/typings/types/types.d.ts +1 -2
- package/package.json +1 -1
- package/dist/typings/builders/buildReassembledFiles.d.ts +0 -1
- package/dist/typings/builders/buildRootElementHeader.d.ts +0 -2
- package/dist/typings/parsers/parseRootElement.d.ts +0 -2
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getLogger, configure } from 'log4js';
|
|
2
|
-
import {
|
|
2
|
+
import { readFile, readdir, stat, writeFile, rm, mkdir, unlink } from 'node:fs/promises';
|
|
3
3
|
import { join, dirname, basename } from 'node:path/posix';
|
|
4
4
|
import { parse, stringify } from 'yaml';
|
|
5
5
|
import { parse as parse$1, stringify as stringify$1 } from 'json5';
|
|
@@ -9,7 +9,7 @@ import { existsSync } from 'node:fs';
|
|
|
9
9
|
import { resolve, relative, dirname as dirname$1, join as join$1, basename as basename$1, extname } from 'node:path';
|
|
10
10
|
import ignore from 'ignore';
|
|
11
11
|
import { createHash } from 'node:crypto';
|
|
12
|
-
import {
|
|
12
|
+
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
|
|
13
13
|
|
|
14
14
|
/******************************************************************************
|
|
15
15
|
Copyright (c) Microsoft Corporation.
|
|
@@ -58,34 +58,6 @@ const XML_PARSER_OPTION = {
|
|
|
58
58
|
};
|
|
59
59
|
const JSON_PARSER_OPTION = Object.assign(Object.assign({}, XML_PARSER_OPTION), { format: true, indentBy: INDENT, suppressBooleanAttributes: false, suppressEmptyNode: false });
|
|
60
60
|
|
|
61
|
-
function buildReassembledFile(combinedXmlContents, reassembledPath, xmlElement, xmlRootElementHeader, xmlDeclarationStr) {
|
|
62
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
-
let finalXmlContent = combinedXmlContents.join("\n");
|
|
64
|
-
const escapedXmlDeclaration = xmlDeclarationStr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
65
|
-
const xmlDeclarationLineRegex = new RegExp(`^\\s*${escapedXmlDeclaration}\\s*$`, "gm");
|
|
66
|
-
finalXmlContent = finalXmlContent.replace(xmlDeclarationLineRegex, "");
|
|
67
|
-
finalXmlContent = finalXmlContent.replace(new RegExp(`<${xmlElement}\\s*[^>]*>`, "g"), "");
|
|
68
|
-
finalXmlContent = finalXmlContent.replace(new RegExp(`</${xmlElement}>`, "g"), "");
|
|
69
|
-
finalXmlContent = finalXmlContent.replace(/<!\[CDATA\[\s*([\s\S]*?)\s*]]>/g, function (_, cdataContent) {
|
|
70
|
-
const trimmedContent = cdataContent.trim();
|
|
71
|
-
const lines = trimmedContent.split("\n");
|
|
72
|
-
const indentedLines = lines.map(function (line) {
|
|
73
|
-
return line.replace(/^\s*/, "");
|
|
74
|
-
});
|
|
75
|
-
return ("<![CDATA[\n" + INDENT + indentedLines.join("\n" + INDENT) + "\n]]>");
|
|
76
|
-
});
|
|
77
|
-
finalXmlContent = finalXmlContent.replace(/(\n\s*){2,}/g, `\n${INDENT}`);
|
|
78
|
-
const closeTag = `</${xmlElement}>`;
|
|
79
|
-
yield writeFile(reassembledPath, `${xmlDeclarationStr}\n${xmlRootElementHeader}${finalXmlContent}${closeTag}`);
|
|
80
|
-
logger.debug(`Created reassembled file: ${reassembledPath}`);
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function buildXMLString(element) {
|
|
85
|
-
const xmlBuilder = new XMLBuilder(JSON_PARSER_OPTION);
|
|
86
|
-
return xmlBuilder.build(element).trimEnd();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
61
|
function stripWhitespaceTextNodes(node) {
|
|
90
62
|
if (Array.isArray(node)) {
|
|
91
63
|
return node.map(stripWhitespaceTextNodes).filter((entry) => {
|
|
@@ -139,45 +111,10 @@ function parseXML(input_1) {
|
|
|
139
111
|
});
|
|
140
112
|
}
|
|
141
113
|
|
|
142
|
-
function buildRootElementHeader(rootElement, rootElementName) {
|
|
143
|
-
let rootElementHeader = `<${rootElementName}`;
|
|
144
|
-
for (const [attrKey, attrValue] of Object.entries(rootElement)) {
|
|
145
|
-
if (attrKey.startsWith("@")) {
|
|
146
|
-
const cleanAttrKey = attrKey.slice(2);
|
|
147
|
-
rootElementHeader += ` ${cleanAttrKey}="${String(attrValue)}"`;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
rootElementHeader += ">";
|
|
151
|
-
return rootElementHeader;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function buildXMLDeclaration(parsedXml) {
|
|
155
|
-
let xmlDeclarationStr = XML_DEFAULT_DECLARATION;
|
|
156
|
-
if (parsedXml["?xml"]) {
|
|
157
|
-
const xmlDeclaration = parsedXml["?xml"];
|
|
158
|
-
const attributes = Object.entries(xmlDeclaration)
|
|
159
|
-
.map(([key, value]) => `${key.replace("@_", "")}="${value}"`)
|
|
160
|
-
.join(" ");
|
|
161
|
-
xmlDeclarationStr = `<?xml ${attributes}?>`;
|
|
162
|
-
}
|
|
163
|
-
return xmlDeclarationStr;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function parseRootElement(xmlParsed) {
|
|
167
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
-
const xmlDeclarationStr = buildXMLDeclaration(xmlParsed);
|
|
169
|
-
const rootElementName = Object.keys(xmlParsed)[1];
|
|
170
|
-
const rootElement = xmlParsed[rootElementName];
|
|
171
|
-
const rootElementHeader = buildRootElementHeader(rootElement, rootElementName);
|
|
172
|
-
return [rootElementName, rootElementHeader, xmlDeclarationStr];
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
114
|
class ReassembleXMLFileHandler {
|
|
177
115
|
processFilesInDirectory(dirPath) {
|
|
178
116
|
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
-
const
|
|
180
|
-
let rootResult = undefined;
|
|
117
|
+
const parsedXmlObjects = [];
|
|
181
118
|
const files = yield readdir(dirPath);
|
|
182
119
|
files.sort((fileA, fileB) => {
|
|
183
120
|
const fullNameA = fileA.split(".")[0].toLowerCase();
|
|
@@ -192,47 +129,44 @@ class ReassembleXMLFileHandler {
|
|
|
192
129
|
const parsedObject = yield this.parseToXmlObject(filePath);
|
|
193
130
|
if (parsedObject === undefined)
|
|
194
131
|
continue;
|
|
195
|
-
|
|
196
|
-
rootResult = rootResultFromFile;
|
|
197
|
-
const combinedXmlString = buildXMLString(parsedObject);
|
|
198
|
-
combinedXmlContents.push(combinedXmlString);
|
|
132
|
+
parsedXmlObjects.push(parsedObject);
|
|
199
133
|
}
|
|
200
134
|
}
|
|
201
135
|
else if (fileStat.isDirectory()) {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
rootResult = subRootResult;
|
|
136
|
+
const subParsedObjects = yield this.processFilesInDirectory(filePath);
|
|
137
|
+
parsedXmlObjects.push(...subParsedObjects);
|
|
205
138
|
}
|
|
206
139
|
}
|
|
207
|
-
return
|
|
140
|
+
return parsedXmlObjects;
|
|
208
141
|
});
|
|
209
142
|
}
|
|
210
143
|
reassemble(xmlAttributes) {
|
|
211
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
212
145
|
const { filePath, fileExtension, postPurge = false } = xmlAttributes;
|
|
213
|
-
let combinedXmlContents = [];
|
|
214
146
|
const fileStat = yield stat(filePath);
|
|
215
147
|
if (!fileStat.isDirectory()) {
|
|
216
148
|
logger.error(`The provided path to reassemble is not a directory: ${filePath}`);
|
|
217
149
|
return;
|
|
218
150
|
}
|
|
219
151
|
logger.debug(`Parsing directory to reassemble: ${filePath}`);
|
|
220
|
-
const
|
|
221
|
-
|
|
152
|
+
const parsedXmlObjects = yield this.processFilesInDirectory(filePath);
|
|
153
|
+
if (!parsedXmlObjects.length) {
|
|
154
|
+
logger.error(`No files under ${filePath} were parsed successfully. A reassembled XML file was not created.`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const { xml: mergedXml, declaration } = mergeXmlElements(parsedXmlObjects);
|
|
158
|
+
const xmlDeclarationStr = createXmlDeclaration(declaration);
|
|
159
|
+
const xmlContent = buildXMLString(mergedXml);
|
|
160
|
+
const finalXml = xmlDeclarationStr + xmlContent;
|
|
222
161
|
const parentDirectory = dirname(filePath);
|
|
223
162
|
const subdirectoryBasename = basename(filePath);
|
|
224
163
|
const fileName = fileExtension
|
|
225
164
|
? `${subdirectoryBasename}.${fileExtension}`
|
|
226
165
|
: `${subdirectoryBasename}.xml`;
|
|
227
166
|
const outputPath = join(parentDirectory, fileName);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
yield
|
|
231
|
-
if (postPurge)
|
|
232
|
-
yield rm(filePath, { recursive: true });
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
logger.error(`No files under ${filePath} were parsed successfully. A reassembled XML file was not created.`);
|
|
167
|
+
yield writeFile(outputPath, finalXml, "utf-8");
|
|
168
|
+
if (postPurge) {
|
|
169
|
+
yield rm(filePath, { recursive: true });
|
|
236
170
|
}
|
|
237
171
|
});
|
|
238
172
|
}
|
|
@@ -262,6 +196,51 @@ class ReassembleXMLFileHandler {
|
|
|
262
196
|
});
|
|
263
197
|
}
|
|
264
198
|
}
|
|
199
|
+
function mergeXmlElements(elements) {
|
|
200
|
+
if (elements.length === 0)
|
|
201
|
+
throw new Error("No elements to merge.");
|
|
202
|
+
const first = elements[0];
|
|
203
|
+
const declaration = first['?xml'];
|
|
204
|
+
const rootKey = Object.keys(first).find((k) => k !== '?xml');
|
|
205
|
+
if (!rootKey) {
|
|
206
|
+
throw new Error("No root element found in the provided XML elements.");
|
|
207
|
+
}
|
|
208
|
+
const mergedContent = {};
|
|
209
|
+
for (const element of elements) {
|
|
210
|
+
const current = element[rootKey];
|
|
211
|
+
for (const [childKey, value] of Object.entries(current)) {
|
|
212
|
+
if (Array.isArray(value)) {
|
|
213
|
+
mergedContent[childKey] = mergedContent[childKey]
|
|
214
|
+
? mergedContent[childKey].concat(value)
|
|
215
|
+
: [...value];
|
|
216
|
+
}
|
|
217
|
+
else if (typeof value === "object") {
|
|
218
|
+
mergedContent[childKey] = mergedContent[childKey]
|
|
219
|
+
? [].concat(mergedContent[childKey], value)
|
|
220
|
+
: [value];
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
if (!mergedContent.hasOwnProperty(childKey)) {
|
|
224
|
+
mergedContent[childKey] = value;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
xml: { [rootKey]: mergedContent },
|
|
231
|
+
declaration,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function createXmlDeclaration(declaration) {
|
|
235
|
+
let declarationStr = `${XML_DEFAULT_DECLARATION}\n`;
|
|
236
|
+
if (declaration) {
|
|
237
|
+
const attributes = Object.entries(declaration)
|
|
238
|
+
.map(([key, value]) => `${key.replace("@_", "")}="${value}"`)
|
|
239
|
+
.join(" ");
|
|
240
|
+
declarationStr = `<?xml ${attributes}?>\n`;
|
|
241
|
+
}
|
|
242
|
+
return declarationStr;
|
|
243
|
+
}
|
|
265
244
|
|
|
266
245
|
function parseUniqueIdElement(element, uniqueIdElements) {
|
|
267
246
|
if (uniqueIdElements === undefined) {
|
|
@@ -292,6 +271,11 @@ function createShortHash(element) {
|
|
|
292
271
|
return fullHash.slice(0, 8);
|
|
293
272
|
}
|
|
294
273
|
|
|
274
|
+
function buildXMLString(element) {
|
|
275
|
+
const xmlBuilder = new XMLBuilder(JSON_PARSER_OPTION);
|
|
276
|
+
return xmlBuilder.build(element).trimEnd();
|
|
277
|
+
}
|
|
278
|
+
|
|
295
279
|
function transformToYaml(xmlPath) {
|
|
296
280
|
return __awaiter(this, void 0, void 0, function* () {
|
|
297
281
|
const parsedXml = yield parseXML(xmlPath);
|
|
@@ -378,26 +362,27 @@ function buildNestedFile(element, disassembledPath, uniqueIdElements, rootElemen
|
|
|
378
362
|
|
|
379
363
|
function parseElement$1(params) {
|
|
380
364
|
return __awaiter(this, void 0, void 0, function* () {
|
|
381
|
-
const { element, disassembledPath, uniqueIdElements, rootElementName, rootAttributes, key,
|
|
382
|
-
if (typeof element === "object") {
|
|
365
|
+
const { element, disassembledPath, uniqueIdElements, rootElementName, rootAttributes, key, leafCount, hasNestedElements, xmlDeclarationStr, format, } = params;
|
|
366
|
+
if (typeof element === "object" && element !== null) {
|
|
383
367
|
yield buildNestedFile(element, disassembledPath, uniqueIdElements, rootElementName, rootAttributes, key, xmlDeclarationStr, format);
|
|
384
|
-
return [
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
const updatedLeafContent = `${leafContent}${indent}<${key}>${String(element)}</${key}>\n`;
|
|
388
|
-
return [updatedLeafContent, leafCount + 1, hasNestedElements];
|
|
368
|
+
return [{}, leafCount, true];
|
|
389
369
|
}
|
|
370
|
+
const leafContent = {
|
|
371
|
+
[key]: element,
|
|
372
|
+
};
|
|
373
|
+
return [leafContent, leafCount + 1, hasNestedElements];
|
|
390
374
|
});
|
|
391
375
|
}
|
|
392
376
|
|
|
393
|
-
function buildLeafFile(leafContent, disassembledPath, baseName, rootElementName,
|
|
377
|
+
function buildLeafFile(leafContent, disassembledPath, baseName, rootElementName, rootAttributes, xmlDeclarationStr, format) {
|
|
394
378
|
return __awaiter(this, void 0, void 0, function* () {
|
|
395
|
-
let leafFile = `${xmlDeclarationStr}\n`;
|
|
396
|
-
leafFile += `${rootElementHeader}\n`;
|
|
397
|
-
leafFile += leafContent;
|
|
398
|
-
leafFile += `</${rootElementName}>`;
|
|
399
379
|
const leafOutputPath = join(disassembledPath, `${baseName}.xml`);
|
|
400
|
-
yield
|
|
380
|
+
yield mkdir(disassembledPath, { recursive: true });
|
|
381
|
+
const wrappedXml = {
|
|
382
|
+
[rootElementName]: Object.assign(Object.assign({}, rootAttributes), leafContent),
|
|
383
|
+
};
|
|
384
|
+
const serialized = `${xmlDeclarationStr}\n${buildXMLString(wrappedXml)}`;
|
|
385
|
+
yield writeFile(leafOutputPath, serialized);
|
|
401
386
|
logger.debug(`Created disassembled file: ${leafOutputPath}`);
|
|
402
387
|
const transformer = getTransformer(format);
|
|
403
388
|
if (transformer) {
|
|
@@ -407,6 +392,18 @@ function buildLeafFile(leafContent, disassembledPath, baseName, rootElementName,
|
|
|
407
392
|
});
|
|
408
393
|
}
|
|
409
394
|
|
|
395
|
+
function buildXMLDeclaration(parsedXml) {
|
|
396
|
+
let xmlDeclarationStr = XML_DEFAULT_DECLARATION;
|
|
397
|
+
if (parsedXml["?xml"]) {
|
|
398
|
+
const xmlDeclaration = parsedXml["?xml"];
|
|
399
|
+
const attributes = Object.entries(xmlDeclaration)
|
|
400
|
+
.map(([key, value]) => `${key.replace("@_", "")}="${value}"`)
|
|
401
|
+
.join(" ");
|
|
402
|
+
xmlDeclarationStr = `<?xml ${attributes}?>`;
|
|
403
|
+
}
|
|
404
|
+
return xmlDeclarationStr;
|
|
405
|
+
}
|
|
406
|
+
|
|
410
407
|
function extractRootAttributes(rootElement) {
|
|
411
408
|
const attributesOnly = {};
|
|
412
409
|
for (const [attrKey, attrValue] of Object.entries(rootElement)) {
|
|
@@ -417,7 +414,7 @@ function extractRootAttributes(rootElement) {
|
|
|
417
414
|
return attributesOnly;
|
|
418
415
|
}
|
|
419
416
|
|
|
420
|
-
function buildDisassembledFiles$1(filePath, disassembledPath, uniqueIdElements, baseName,
|
|
417
|
+
function buildDisassembledFiles$1(filePath, disassembledPath, uniqueIdElements, baseName, postPurge, format) {
|
|
421
418
|
return __awaiter(this, void 0, void 0, function* () {
|
|
422
419
|
const parsedXml = yield parseXML(filePath);
|
|
423
420
|
if (parsedXml === undefined)
|
|
@@ -425,49 +422,40 @@ function buildDisassembledFiles$1(filePath, disassembledPath, uniqueIdElements,
|
|
|
425
422
|
const rootElementName = Object.keys(parsedXml)[1];
|
|
426
423
|
const xmlDeclarationStr = buildXMLDeclaration(parsedXml);
|
|
427
424
|
const rootElement = parsedXml[rootElementName];
|
|
428
|
-
const rootElementHeader = buildRootElementHeader(rootElement, rootElementName);
|
|
429
425
|
const rootAttributes = extractRootAttributes(rootElement);
|
|
430
|
-
let leafContent =
|
|
426
|
+
let leafContent = {};
|
|
431
427
|
let leafCount = 0;
|
|
432
428
|
let hasNestedElements = false;
|
|
433
|
-
for (const key of Object.keys(rootElement).filter((
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
rootElementName,
|
|
441
|
-
rootAttributes,
|
|
442
|
-
key,
|
|
443
|
-
indent,
|
|
444
|
-
leafContent,
|
|
445
|
-
leafCount,
|
|
446
|
-
hasNestedElements,
|
|
447
|
-
xmlDeclarationStr,
|
|
448
|
-
format,
|
|
449
|
-
});
|
|
450
|
-
leafContent = updatedLeafContent;
|
|
451
|
-
leafCount = updatedLeafCount;
|
|
452
|
-
hasNestedElements = updatedHasNestedElements;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
const [updatedLeafContent, updatedLeafCount, updatedHasNestedElements] = yield parseElement$1({
|
|
457
|
-
element: rootElement[key],
|
|
429
|
+
for (const key of Object.keys(rootElement).filter((k) => !k.startsWith("@"))) {
|
|
430
|
+
const elements = Array.isArray(rootElement[key])
|
|
431
|
+
? rootElement[key]
|
|
432
|
+
: [rootElement[key]];
|
|
433
|
+
for (const element of elements) {
|
|
434
|
+
const [parsedLeafContent, updatedLeafCount, updatedHasNestedElements] = yield parseElement$1({
|
|
435
|
+
element,
|
|
458
436
|
disassembledPath,
|
|
459
437
|
uniqueIdElements,
|
|
460
438
|
rootElementName,
|
|
461
439
|
rootAttributes,
|
|
462
440
|
key,
|
|
463
|
-
indent,
|
|
464
|
-
leafContent,
|
|
465
441
|
leafCount,
|
|
466
442
|
hasNestedElements,
|
|
467
443
|
xmlDeclarationStr,
|
|
468
444
|
format,
|
|
469
445
|
});
|
|
470
|
-
|
|
446
|
+
const newContent = parsedLeafContent[key];
|
|
447
|
+
if (newContent !== undefined) {
|
|
448
|
+
const existing = leafContent[key];
|
|
449
|
+
const existingArray = Array.isArray(existing)
|
|
450
|
+
? existing
|
|
451
|
+
: existing !== undefined
|
|
452
|
+
? [existing]
|
|
453
|
+
: [];
|
|
454
|
+
const incomingArray = Array.isArray(newContent)
|
|
455
|
+
? newContent
|
|
456
|
+
: [newContent];
|
|
457
|
+
leafContent[key] = [...existingArray, ...incomingArray];
|
|
458
|
+
}
|
|
471
459
|
leafCount = updatedLeafCount;
|
|
472
460
|
hasNestedElements = updatedHasNestedElements;
|
|
473
461
|
}
|
|
@@ -477,38 +465,41 @@ function buildDisassembledFiles$1(filePath, disassembledPath, uniqueIdElements,
|
|
|
477
465
|
return;
|
|
478
466
|
}
|
|
479
467
|
if (leafCount > 0) {
|
|
480
|
-
yield buildLeafFile(leafContent, disassembledPath, baseName, rootElementName,
|
|
468
|
+
yield buildLeafFile(leafContent, disassembledPath, baseName, rootElementName, rootAttributes, xmlDeclarationStr, format);
|
|
481
469
|
}
|
|
482
470
|
if (postPurge) {
|
|
483
|
-
unlink(filePath);
|
|
471
|
+
yield unlink(filePath);
|
|
484
472
|
}
|
|
485
473
|
});
|
|
486
474
|
}
|
|
487
475
|
|
|
488
476
|
function parseElement(params) {
|
|
489
477
|
return __awaiter(this, void 0, void 0, function* () {
|
|
490
|
-
const { element, key,
|
|
478
|
+
const { element, key, hasNestedElements } = params;
|
|
491
479
|
const nestedGroups = {};
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
480
|
+
const isArray = Array.isArray(element);
|
|
481
|
+
const isObjectWithMultipleFields = typeof element === "object" &&
|
|
482
|
+
element !== null &&
|
|
483
|
+
Object.keys(element).length > 1;
|
|
484
|
+
const isNested = isArray || isObjectWithMultipleFields;
|
|
485
|
+
if (isNested) {
|
|
486
|
+
nestedGroups[key] = [element];
|
|
496
487
|
return {
|
|
497
|
-
leafContent,
|
|
498
|
-
leafCount,
|
|
488
|
+
leafContent: {},
|
|
489
|
+
leafCount: params.leafCount,
|
|
499
490
|
hasNestedElements: true,
|
|
500
491
|
nestedGroups,
|
|
501
492
|
};
|
|
502
493
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}
|
|
494
|
+
const leafContent = {
|
|
495
|
+
[key]: element,
|
|
496
|
+
};
|
|
497
|
+
return {
|
|
498
|
+
leafContent,
|
|
499
|
+
leafCount: params.leafCount + 1,
|
|
500
|
+
hasNestedElements,
|
|
501
|
+
nestedGroups,
|
|
502
|
+
};
|
|
512
503
|
});
|
|
513
504
|
}
|
|
514
505
|
|
|
@@ -530,21 +521,31 @@ function buildGroupedNestedFile(tag, elements, disassembledPath, rootElementName
|
|
|
530
521
|
});
|
|
531
522
|
}
|
|
532
523
|
|
|
533
|
-
function
|
|
524
|
+
function orderXmlElementKeys(content, keyOrder) {
|
|
525
|
+
const ordered = {};
|
|
526
|
+
for (const key of keyOrder) {
|
|
527
|
+
if (content[key] !== undefined) {
|
|
528
|
+
ordered[key] = content[key];
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return ordered;
|
|
532
|
+
}
|
|
533
|
+
function buildDisassembledFiles(filePath, disassembledPath, baseName, postPurge, format) {
|
|
534
534
|
return __awaiter(this, void 0, void 0, function* () {
|
|
535
|
+
var _a;
|
|
535
536
|
const parsedXml = yield parseXML(filePath);
|
|
536
537
|
if (parsedXml === undefined)
|
|
537
538
|
return;
|
|
538
539
|
const rootElementName = Object.keys(parsedXml)[1];
|
|
539
540
|
const xmlDeclarationStr = buildXMLDeclaration(parsedXml);
|
|
540
541
|
const rootElement = parsedXml[rootElementName];
|
|
541
|
-
const rootElementHeader = buildRootElementHeader(rootElement, rootElementName);
|
|
542
542
|
const rootAttributes = extractRootAttributes(rootElement);
|
|
543
|
-
let leafContent =
|
|
543
|
+
let leafContent = {};
|
|
544
544
|
let leafCount = 0;
|
|
545
545
|
let hasNestedElements = false;
|
|
546
546
|
const nestedGroups = {};
|
|
547
|
-
|
|
547
|
+
const keyOrder = Object.keys(parsedXml[rootElementName]).filter((k) => !k.startsWith("@"));
|
|
548
|
+
for (const key of keyOrder) {
|
|
548
549
|
const elements = Array.isArray(rootElement[key])
|
|
549
550
|
? rootElement[key]
|
|
550
551
|
: [rootElement[key]];
|
|
@@ -552,21 +553,33 @@ function buildDisassembledFiles(filePath, disassembledPath, baseName, indent, po
|
|
|
552
553
|
const result = yield parseElement({
|
|
553
554
|
element,
|
|
554
555
|
key,
|
|
555
|
-
indent,
|
|
556
|
-
leafContent,
|
|
557
556
|
leafCount,
|
|
558
557
|
hasNestedElements});
|
|
559
|
-
|
|
558
|
+
if (Object.keys(result.leafContent).length > 0) {
|
|
559
|
+
const newContent = result.leafContent[key];
|
|
560
|
+
if (newContent !== undefined) {
|
|
561
|
+
const existing = leafContent[key];
|
|
562
|
+
const existingArray = Array.isArray(existing)
|
|
563
|
+
? existing
|
|
564
|
+
: existing !== undefined
|
|
565
|
+
? [existing]
|
|
566
|
+
: [];
|
|
567
|
+
const incomingArray = Array.isArray(newContent)
|
|
568
|
+
? newContent
|
|
569
|
+
: [newContent];
|
|
570
|
+
leafContent[key] = [...existingArray, ...incomingArray];
|
|
571
|
+
}
|
|
572
|
+
}
|
|
560
573
|
leafCount = result.leafCount;
|
|
561
574
|
hasNestedElements = result.hasNestedElements;
|
|
562
575
|
for (const tag in result.nestedGroups) {
|
|
563
576
|
if (!nestedGroups[tag])
|
|
564
577
|
nestedGroups[tag] = [];
|
|
565
|
-
nestedGroups[tag].push(...result.nestedGroups[tag]);
|
|
578
|
+
nestedGroups[tag].push(...((_a = result.nestedGroups[tag]) !== null && _a !== void 0 ? _a : []));
|
|
566
579
|
}
|
|
567
580
|
}
|
|
568
581
|
}
|
|
569
|
-
if (!hasNestedElements) {
|
|
582
|
+
if (!hasNestedElements && leafCount > 0) {
|
|
570
583
|
logger.error(`The XML file ${filePath} only has leaf elements. This file will not be disassembled.`);
|
|
571
584
|
return;
|
|
572
585
|
}
|
|
@@ -574,7 +587,8 @@ function buildDisassembledFiles(filePath, disassembledPath, baseName, indent, po
|
|
|
574
587
|
yield buildGroupedNestedFile(tag, nestedGroups[tag], disassembledPath, rootElementName, rootAttributes, xmlDeclarationStr, format);
|
|
575
588
|
}
|
|
576
589
|
if (leafCount > 0) {
|
|
577
|
-
|
|
590
|
+
const orderedLeafContent = orderXmlElementKeys(leafContent, keyOrder);
|
|
591
|
+
yield buildLeafFile(orderedLeafContent, disassembledPath, baseName, rootElementName, rootAttributes, xmlDeclarationStr, format);
|
|
578
592
|
}
|
|
579
593
|
if (postPurge) {
|
|
580
594
|
yield unlink(filePath);
|
|
@@ -652,10 +666,10 @@ class DisassembleXMLFileHandler {
|
|
|
652
666
|
if (prePurge && existsSync(outputPath))
|
|
653
667
|
yield rm(outputPath, { recursive: true });
|
|
654
668
|
if (strategy === "grouped-by-tag") {
|
|
655
|
-
yield buildDisassembledFiles(filePath, outputPath, fullName,
|
|
669
|
+
yield buildDisassembledFiles(filePath, outputPath, fullName, postPurge, format);
|
|
656
670
|
}
|
|
657
671
|
else {
|
|
658
|
-
yield buildDisassembledFiles$1(filePath, outputPath, uniqueIdElements, fullName,
|
|
672
|
+
yield buildDisassembledFiles$1(filePath, outputPath, uniqueIdElements, fullName, postPurge, format);
|
|
659
673
|
}
|
|
660
674
|
});
|
|
661
675
|
}
|