utils.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. const xml2js = require("xml2js");
  2. const builder = require("xmlbuilder");
  3. const OPTIONS = {
  4. headless: true,
  5. explicitChildren: true,
  6. preserveChildrenOrder: true,
  7. charsAsChildren: true,
  8. };
  9. function parseXml(doc) {
  10. let document;
  11. const parser = new xml2js.Parser(OPTIONS);
  12. parser.parseString(doc, (err, result) => {
  13. document = result;
  14. });
  15. return document;
  16. }
  17. function renderXml(doc) {
  18. const rootName = Object.keys(doc)[0];
  19. const xml = builder.create(rootName, null, null, { headless: true });
  20. const renderChildren = (nodes, xml) => {
  21. nodes.forEach((node) => {
  22. const elem = xml.ele(node["#name"]);
  23. if (node.$) Object.keys(node.$).forEach((key) => elem.att(key, node.$[key]));
  24. if (node.$$) renderChildren(node.$$, elem);
  25. });
  26. };
  27. renderChildren(doc[rootName].$$, xml);
  28. return xml.end({ pretty: true });
  29. }
  30. function countRegionsInResult(result) {
  31. return result.reduce(
  32. (res, r) => {
  33. if ((!res.ids[r.id] && Object.keys(r.value).length > 1) || !!r.value.points) {
  34. res.count++;
  35. res.ids[r.id] = true;
  36. }
  37. return res;
  38. },
  39. { count: 0, ids: {} },
  40. ).count;
  41. }
  42. function xmlForEachNode(tree, cb) {
  43. function forEachNode(node) {
  44. cb(node);
  45. if (node.$$) {
  46. node.$$.forEach((childNode) => forEachNode(childNode));
  47. }
  48. }
  49. forEachNode(Object.values(tree)[0]);
  50. }
  51. function xmlFilterNodes(tree, cb) {
  52. function filterChildren(node) {
  53. cb(node);
  54. if (node.$$) {
  55. node.$$ = node.$$.filter((childNode) => {
  56. if (!cb(childNode)) return false;
  57. filterChildren(childNode);
  58. return true;
  59. });
  60. }
  61. }
  62. const rootNode = Object.values(tree)[0];
  63. if (cb(rootNode)) {
  64. filterChildren(rootNode);
  65. }
  66. return {};
  67. }
  68. function xmlTreeHasTag(tree, tagName) {
  69. return xmlFindBy(tree, (node) => node["#name"] === tagName);
  70. }
  71. function xmlFindBy(tree, cb) {
  72. function findBy(node) {
  73. if (cb(node)) return node;
  74. return !!node.$$ && node.$$.find((childNode) => findBy(childNode));
  75. }
  76. const rootNode = Object.values(tree)[0];
  77. return findBy(rootNode);
  78. }
  79. module.exports = {
  80. parseXml,
  81. renderXml,
  82. xmlForEachNode,
  83. xmlFindBy,
  84. xmlTreeHasTag,
  85. xmlFilterNodes,
  86. countRegionsInResult,
  87. };