const xml2js = require("xml2js");
|
const builder = require("xmlbuilder");
|
const OPTIONS = {
|
headless: true,
|
explicitChildren: true,
|
preserveChildrenOrder: true,
|
charsAsChildren: true,
|
};
|
|
function parseXml(doc) {
|
let document;
|
const parser = new xml2js.Parser(OPTIONS);
|
|
parser.parseString(doc, (err, result) => {
|
document = result;
|
});
|
return document;
|
}
|
function renderXml(doc) {
|
const rootName = Object.keys(doc)[0];
|
const xml = builder.create(rootName, null, null, { headless: true });
|
const renderChildren = (nodes, xml) => {
|
nodes.forEach((node) => {
|
const elem = xml.ele(node["#name"]);
|
|
if (node.$) Object.keys(node.$).forEach((key) => elem.att(key, node.$[key]));
|
if (node.$$) renderChildren(node.$$, elem);
|
});
|
};
|
|
renderChildren(doc[rootName].$$, xml);
|
return xml.end({ pretty: true });
|
}
|
|
function countRegionsInResult(result) {
|
return result.reduce(
|
(res, r) => {
|
if ((!res.ids[r.id] && Object.keys(r.value).length > 1) || !!r.value.points) {
|
res.count++;
|
res.ids[r.id] = true;
|
}
|
return res;
|
},
|
{ count: 0, ids: {} },
|
).count;
|
}
|
|
function xmlForEachNode(tree, cb) {
|
function forEachNode(node) {
|
cb(node);
|
if (node.$$) {
|
node.$$.forEach((childNode) => forEachNode(childNode));
|
}
|
}
|
forEachNode(Object.values(tree)[0]);
|
}
|
|
function xmlFilterNodes(tree, cb) {
|
function filterChildren(node) {
|
cb(node);
|
if (node.$$) {
|
node.$$ = node.$$.filter((childNode) => {
|
if (!cb(childNode)) return false;
|
filterChildren(childNode);
|
return true;
|
});
|
}
|
}
|
const rootNode = Object.values(tree)[0];
|
|
if (cb(rootNode)) {
|
filterChildren(rootNode);
|
}
|
return {};
|
}
|
|
function xmlTreeHasTag(tree, tagName) {
|
return xmlFindBy(tree, (node) => node["#name"] === tagName);
|
}
|
|
function xmlFindBy(tree, cb) {
|
function findBy(node) {
|
if (cb(node)) return node;
|
return !!node.$$ && node.$$.find((childNode) => findBy(childNode));
|
}
|
const rootNode = Object.values(tree)[0];
|
|
return findBy(rootNode);
|
}
|
|
module.exports = {
|
parseXml,
|
renderXml,
|
xmlForEachNode,
|
xmlFindBy,
|
xmlTreeHasTag,
|
xmlFilterNodes,
|
countRegionsInResult,
|
};
|