node2json.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. 'use strict';
  2. /**
  3. *
  4. * @param {array} node
  5. * @param {any} options
  6. * @returns
  7. */
  8. function prettify(node, options){
  9. return compress( node, options);
  10. }
  11. /**
  12. *
  13. * @param {array} arr
  14. * @param {object} options
  15. * @param {string} jPath
  16. * @returns object
  17. */
  18. function compress(arr, options, jPath){
  19. let text;
  20. const compressedObj = {};
  21. for (let i = 0; i < arr.length; i++) {
  22. const tagObj = arr[i];
  23. const property = propName(tagObj);
  24. let newJpath = "";
  25. if(jPath === undefined) newJpath = property;
  26. else newJpath = jPath + "." + property;
  27. if(property === options.textNodeName){
  28. if(text === undefined) text = tagObj[property];
  29. else text += "" + tagObj[property];
  30. }else if(property === undefined){
  31. continue;
  32. }else if(tagObj[property]){
  33. let val = compress(tagObj[property], options, newJpath);
  34. const isLeaf = isLeafTag(val, options);
  35. if(tagObj[":@"]){
  36. assignAttributes( val, tagObj[":@"], newJpath, options);
  37. }else if(Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode){
  38. val = val[options.textNodeName];
  39. }else if(Object.keys(val).length === 0){
  40. if(options.alwaysCreateTextNode) val[options.textNodeName] = "";
  41. else val = "";
  42. }
  43. if(compressedObj[property] !== undefined && compressedObj.hasOwnProperty(property)) {
  44. if(!Array.isArray(compressedObj[property])) {
  45. compressedObj[property] = [ compressedObj[property] ];
  46. }
  47. compressedObj[property].push(val);
  48. }else{
  49. //TODO: if a node is not an array, then check if it should be an array
  50. //also determine if it is a leaf node
  51. if (options.isArray(property, newJpath, isLeaf )) {
  52. compressedObj[property] = [val];
  53. }else{
  54. compressedObj[property] = val;
  55. }
  56. }
  57. }
  58. }
  59. // if(text && text.length > 0) compressedObj[options.textNodeName] = text;
  60. if(typeof text === "string"){
  61. if(text.length > 0) compressedObj[options.textNodeName] = text;
  62. }else if(text !== undefined) compressedObj[options.textNodeName] = text;
  63. return compressedObj;
  64. }
  65. function propName(obj){
  66. const keys = Object.keys(obj);
  67. for (let i = 0; i < keys.length; i++) {
  68. const key = keys[i];
  69. if(key !== ":@") return key;
  70. }
  71. }
  72. function assignAttributes(obj, attrMap, jpath, options){
  73. if (attrMap) {
  74. const keys = Object.keys(attrMap);
  75. const len = keys.length; //don't make it inline
  76. for (let i = 0; i < len; i++) {
  77. const atrrName = keys[i];
  78. if (options.isArray(atrrName, jpath + "." + atrrName, true, true)) {
  79. obj[atrrName] = [ attrMap[atrrName] ];
  80. } else {
  81. obj[atrrName] = attrMap[atrrName];
  82. }
  83. }
  84. }
  85. }
  86. function isLeafTag(obj, options){
  87. const { textNodeName } = options;
  88. const propCount = Object.keys(obj).length;
  89. if (propCount === 0) {
  90. return true;
  91. }
  92. if (
  93. propCount === 1 &&
  94. (obj[textNodeName] || typeof obj[textNodeName] === "boolean" || obj[textNodeName] === 0)
  95. ) {
  96. return true;
  97. }
  98. return false;
  99. }
  100. exports.prettify = prettify;