xml.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.parseXml = parseXml;
  6. exports.XElement = void 0;
  7. function sax() {
  8. const data = _interopRequireWildcard(require("sax"));
  9. sax = function () {
  10. return data;
  11. };
  12. return data;
  13. }
  14. function _index() {
  15. const data = require("./index");
  16. _index = function () {
  17. return data;
  18. };
  19. return data;
  20. }
  21. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
  22. class XElement {
  23. constructor(name) {
  24. this.name = name;
  25. this.value = "";
  26. this.attributes = null;
  27. this.isCData = false;
  28. this.elements = null;
  29. if (!name) {
  30. throw (0, _index().newError)("Element name cannot be empty", "ERR_XML_ELEMENT_NAME_EMPTY");
  31. }
  32. if (!isValidName(name)) {
  33. throw (0, _index().newError)(`Invalid element name: ${name}`, "ERR_XML_ELEMENT_INVALID_NAME");
  34. }
  35. }
  36. attribute(name) {
  37. const result = this.attributes === null ? null : this.attributes[name];
  38. if (result == null) {
  39. throw (0, _index().newError)(`No attribute "${name}"`, "ERR_XML_MISSED_ATTRIBUTE");
  40. }
  41. return result;
  42. }
  43. removeAttribute(name) {
  44. if (this.attributes !== null) {
  45. delete this.attributes[name];
  46. }
  47. }
  48. element(name, ignoreCase = false, errorIfMissed = null) {
  49. const result = this.elementOrNull(name, ignoreCase);
  50. if (result === null) {
  51. throw (0, _index().newError)(errorIfMissed || `No element "${name}"`, "ERR_XML_MISSED_ELEMENT");
  52. }
  53. return result;
  54. }
  55. elementOrNull(name, ignoreCase = false) {
  56. if (this.elements === null) {
  57. return null;
  58. }
  59. for (const element of this.elements) {
  60. if (isNameEquals(element, name, ignoreCase)) {
  61. return element;
  62. }
  63. }
  64. return null;
  65. }
  66. getElements(name, ignoreCase = false) {
  67. if (this.elements === null) {
  68. return [];
  69. }
  70. return this.elements.filter(it => isNameEquals(it, name, ignoreCase));
  71. }
  72. elementValueOrEmpty(name, ignoreCase = false) {
  73. const element = this.elementOrNull(name, ignoreCase);
  74. return element === null ? "" : element.value;
  75. }
  76. }
  77. exports.XElement = XElement;
  78. const NAME_REG_EXP = new RegExp(/^[A-Za-z_][:A-Za-z0-9_-]*$/i);
  79. function isValidName(name) {
  80. return NAME_REG_EXP.test(name);
  81. }
  82. function isNameEquals(element, name, ignoreCase) {
  83. const elementName = element.name;
  84. return elementName === name || ignoreCase === true && elementName.length === name.length && elementName.toLowerCase() === name.toLowerCase();
  85. }
  86. function parseXml(data) {
  87. let rootElement = null;
  88. const parser = sax().parser(true, {});
  89. const elements = [];
  90. parser.onopentag = saxElement => {
  91. const element = new XElement(saxElement.name);
  92. element.attributes = saxElement.attributes;
  93. if (rootElement === null) {
  94. rootElement = element;
  95. } else {
  96. const parent = elements[elements.length - 1];
  97. if (parent.elements == null) {
  98. parent.elements = [];
  99. }
  100. parent.elements.push(element);
  101. }
  102. elements.push(element);
  103. };
  104. parser.onclosetag = () => {
  105. elements.pop();
  106. };
  107. parser.ontext = text => {
  108. if (elements.length > 0) {
  109. elements[elements.length - 1].value = text;
  110. }
  111. };
  112. parser.oncdata = cdata => {
  113. const element = elements[elements.length - 1];
  114. element.value = cdata;
  115. element.isCData = true;
  116. };
  117. parser.onerror = err => {
  118. throw err;
  119. };
  120. parser.write(data);
  121. return rootElement;
  122. }
  123. //# sourceMappingURL=xml.js.map