-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
96 lines (93 loc) · 3 KB
/
index.js
File metadata and controls
96 lines (93 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*jshint esversion: 6 */
const convert = require("xml-js");
const _ = require("lodash");
/**
* @author AKASH J P ,Gokulnath
* @param {String} xml (Mandatory)
* @param {JSON} options (Optional)
* @param options.crossReference {Regex} example x_(.*)
*/
const xmlPathResolver = (xml, { crossRefKey = "id" , ...rest } = {}) => {
try {
if (!xml) {
throw new Error("First argument should have xml");
}
let jsonFormOfXml = convert.xml2json(xml, { compact: true, spaces: 4 });
let refpaths = extractArrayPaths(JSON.parse(jsonFormOfXml)).arrayPaths;
let modifiedJson = resolveCrossRefs(jsonFormOfXml, { crossRefKey, ...rest }, refpaths);
return modifiedJson;
} catch (Err) {
console.log(`error in xmlpathresolver`, Err);
throw Err;
}
};
function extractArrayPaths(obj, prefix, current, arrayPaths) {
try {
prefix = prefix || [];
current = current || {};
arrayPaths = arrayPaths || {};
if (typeof (obj) === 'object' && obj !== null && !_.isArray(obj)) {
Object.keys(obj).forEach(key => {
extractArrayPaths(obj[key], prefix.concat(key), current, arrayPaths);
});
}
else if (_.isArray(obj)) {
let lastPrefix = prefix[prefix.length - 1];
if (arrayPaths[lastPrefix] && _.isArray(arrayPaths[lastPrefix])) {
arrayPaths[lastPrefix] = [...arrayPaths[lastPrefix], ...obj];
} else {
arrayPaths[lastPrefix] = obj;
}
}
else {
current[prefix.join('.')] = obj;
}
if (_.isObject(obj) && !_.isArray(obj)) {
let lastPrefix = prefix[prefix.length - 1];
if (arrayPaths[lastPrefix]) {
arrayPaths[lastPrefix].push(obj);
}
else {
arrayPaths[lastPrefix] = [obj];
}
}
return { current, arrayPaths };
} catch (err) {
throw err;
}
}
function resolveCrossRefs(jsonFormOfXml, options, refpaths, level = 0) {
try {
return JSON.parse(jsonFormOfXml, (key, value) => {
if (options.crossReference && options.crossReference instanceof RegExp) {
if (options.crossReference.test(key)) {
let matches = options.crossReference.exec(key);
if (_.isArray(matches) && matches.length >= 1) {
let path = matches[1];
try {
if (refpaths[path]) {
let extractedRefsValue = refpaths[path].filter((path) => {
return path._attributes[options.crossRefKey] === value;
});
extractedRefsValue = _.get(extractedRefsValue, "0", value);
if (level > 150) {
throw new Error("Nesting level threshold reached");
}
let resolvedRefs = resolveCrossRefs(JSON.stringify(extractedRefsValue), options, refpaths, level + 1);
return resolvedRefs;
}
} catch (err) {
throw err;
}
}
return value;
}
return value;
}
return value;
});
} catch (err) {
throw err;
}
}
module.exports = xmlPathResolver;