UNPKG

projen

Version:

CDK for software projects

141 lines 7.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XMLReader = void 0; const XMLStringLexer_1 = require("@oozcitak/dom/lib/parser/XMLStringLexer"); const interfaces_1 = require("@oozcitak/dom/lib/parser/interfaces"); const interfaces_2 = require("@oozcitak/dom/lib/dom/interfaces"); const infra_1 = require("@oozcitak/infra"); const algorithm_1 = require("@oozcitak/dom/lib/algorithm"); const BaseReader_1 = require("./BaseReader"); /** * Parses XML nodes from an XML document string. */ class XMLReader extends BaseReader_1.BaseReader { /** * Parses the given document representation. * * @param node - node receive parsed XML nodes * @param str - XML document string to parse */ _parse(node, str) { const lexer = new XMLStringLexer_1.XMLStringLexer(str, { skipWhitespaceOnlyText: this._builderOptions.skipWhitespaceOnlyText }); let lastChild = node; let context = node; let token = lexer.nextToken(); while (token.type !== interfaces_1.TokenType.EOF) { switch (token.type) { case interfaces_1.TokenType.Declaration: const declaration = token; const version = this.sanitize(declaration.version); if (version !== "1.0") { throw new Error("Invalid xml version: " + version); } const builderOptions = { version: version }; if (declaration.encoding) { builderOptions.encoding = this.sanitize(declaration.encoding); } if (declaration.standalone) { builderOptions.standalone = (this.sanitize(declaration.standalone) === "yes"); } context.set(builderOptions); break; case interfaces_1.TokenType.DocType: const doctype = token; context = this.docType(context, this.sanitize(doctype.name), this.sanitize(doctype.pubId), this.sanitize(doctype.sysId)) || context; break; case interfaces_1.TokenType.CDATA: const cdata = token; context = this.cdata(context, this.sanitize(cdata.data)) || context; break; case interfaces_1.TokenType.Comment: const comment = token; context = this.comment(context, this.sanitize(comment.data)) || context; break; case interfaces_1.TokenType.PI: const pi = token; context = this.instruction(context, this.sanitize(pi.target), this.sanitize(pi.data)) || context; break; case interfaces_1.TokenType.Text: if (context.node.nodeType === interfaces_2.NodeType.Document) break; const text = token; context = this.text(context, this._decodeText(this.sanitize(text.data))) || context; break; case interfaces_1.TokenType.Element: const element = token; const elementName = this.sanitize(element.name); // inherit namespace from parent const [prefix] = (0, algorithm_1.namespace_extractQName)(elementName); let namespace = context.node.lookupNamespaceURI(prefix); // override namespace if there is a namespace declaration // attribute // also lookup namespace declaration attributes const nsDeclarations = {}; for (let [attName, attValue] of element.attributes) { attName = this.sanitize(attName); attValue = this.sanitize(attValue); if (attName === "xmlns") { namespace = attValue; } else { const [attPrefix, attLocalName] = (0, algorithm_1.namespace_extractQName)(attName); if (attPrefix === "xmlns") { if (attLocalName === prefix) { namespace = attValue; } nsDeclarations[attLocalName] = attValue; } } } // create the DOM element node const elementNode = (namespace !== null ? this.element(context, namespace, elementName) : this.element(context, undefined, elementName)); if (elementNode === undefined) break; if (context.node === node.node) lastChild = elementNode; // assign attributes for (let [attName, attValue] of element.attributes) { attName = this.sanitize(attName); attValue = this.sanitize(attValue); const [attPrefix, attLocalName] = (0, algorithm_1.namespace_extractQName)(attName); let attNamespace = null; if (attPrefix === "xmlns" || (attPrefix === null && attLocalName === "xmlns")) { // namespace declaration attribute attNamespace = infra_1.namespace.XMLNS; } else { attNamespace = elementNode.node.lookupNamespaceURI(attPrefix); if (attNamespace !== null && elementNode.node.isDefaultNamespace(attNamespace)) { attNamespace = null; } else if (attNamespace === null && attPrefix !== null) { attNamespace = nsDeclarations[attPrefix] || null; } } if (attNamespace !== null) this.attribute(elementNode, attNamespace, attName, this._decodeAttributeValue(attValue)); else this.attribute(elementNode, undefined, attName, this._decodeAttributeValue(attValue)); } if (!element.selfClosing) { context = elementNode; } break; case interfaces_1.TokenType.ClosingTag: /* istanbul ignore else */ if (context.node.parentNode) { context = context.up(); } break; } token = lexer.nextToken(); } return lastChild; } } exports.XMLReader = XMLReader; //# sourceMappingURL=XMLReader.js.map