UNPKG

xml2o

Version:

Helps you convert XML into an object for easy reading.

124 lines (118 loc) 3.89 kB
// src/index.ts import SAX from "sax"; // src/node/index.ts var text = Symbol(); class Node extends Array { parent; [text]; name; local; path; prefix; uri; attributes; constructor(opt, parent) { super(); this.parent = parent; this.name = opt.name, this.local = opt.local, this.prefix = opt.prefix, this.uri = opt.uri || "", this.attributes = Object.assign({}, ...Object.keys(opt.attributes).map((key) => ({ [key]: new Attribute(opt.attributes[key]) }))), this[text] = []; } get root() { return this.parent ? this.parent.root : this; } get text() { return this[text].join(""); } static pushText(node, value) { if (node[text].push(value), node.parent) node.parent[text].push(value); } static addNode(parent, opt) { let node = new Node(opt, parent); return parent.push(node), node; } getAttributes(uri) { return Object.assign({}, ...Object.keys(this.attributes).filter((key) => { let attribute = this.attributes[key]; return uri && attribute.uri === uri || !uri && !attribute.uri; }).map((key) => ({ [this.attributes[key].local]: this.attributes[key].value }))); } getAttribute(name, uri) { let attribute = this.getAttributeNode(name, uri) || { value: void 0 }; if (attribute) return attribute.value; } getAttributeNode(name, uri) { return Object.entries(this.attributes).filter(([, attribute]) => { if (name && uri) return name === attribute.local && uri === attribute.uri; return attribute.name === name; }).map(([, attribute]) => attribute).shift(); } hasAttribute(name, uri) { return !!this.getAttributeNode(name, uri); } query(path, uri) { let result = [], searchUri = uri || "", match; if (path === "/") return [this]; if (path.indexOf("/") === 0) { let parts = path.split("/").slice(1); if (parts.length === 1) match = (node) => parts[0] === node.local && searchUri === node.uri ? [node] : []; else if (parts.length > 1) match = (node) => parts[0] === node.local ? [...node.query("/".concat(parts.slice(1).join("/")), uri)] : []; else return []; } else if (path.indexOf("/") !== -1) { let parts = path.split("/"); match = (node) => parts[0] === node.local ? [...node.query(parts.slice(1).join("/"), uri)] : [...node.query(path, uri)]; } else match = (node) => path === node.local && searchUri === node.uri ? [node, ...node.query(path, uri)] : [...node.query(path, uri)]; for (let node of this) result.push(...match(node)); return result; } } class Attribute { name; local; value; prefix; uri; constructor(opt) { this.value = opt.value, this.prefix = opt.prefix, this.name = opt.name, this.local = opt.local, this.uri = opt.uri; } toString() { return this.value; } } // src/index.ts function convert(parser, ready) { let pointer; return parser.on("opentag", (node) => { if (!pointer) pointer = new Node(node, null); else pointer = Node.addNode(pointer, node); }), parser.on("closetag", (_node) => pointer.parent ? pointer = pointer.parent : null), parser.on("text", (value) => pointer && Node.pushText(pointer, value)), parser.on("cdata", (value) => Node.pushText(pointer, value)), new Promise((resolve, reject) => { parser.on("end", () => resolve(pointer)), parser.on("error", (error) => reject(error)), ready(); }); } function convertStream(stream) { let parser = SAX.createStream(!0, { xmlns: !0 }); return convert(parser, () => stream.pipe(parser)); } function convertString(XMLString) { let parser = SAX.createStream(!0, { xmlns: !0 }); return convert(parser, () => parser.end(XMLString)); } export { convertString, convertStream, Node, Attribute }; //# debugId=85677FEC7D0996C264756E2164756E21 //# sourceMappingURL=index.mjs.map