UNPKG

@genexus/web-standard-functions

Version:

GeneXus JavaScript standard functions library for web generators

563 lines 16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XMLReader = void 0; const helpers_1 = require("../misc/helpers"); const xmlcommon_1 = require("./xmlcommon"); var GXNodeType; (function (GXNodeType) { GXNodeType[GXNodeType["element"] = 1] = "element"; GXNodeType[GXNodeType["endTag"] = 2] = "endTag"; GXNodeType[GXNodeType["text"] = 4] = "text"; GXNodeType[GXNodeType["comment"] = 8] = "comment"; GXNodeType[GXNodeType["whiteSpace"] = 16] = "whiteSpace"; GXNodeType[GXNodeType["cdata"] = 32] = "cdata"; GXNodeType[GXNodeType["processingInstruction"] = 64] = "processingInstruction"; GXNodeType[GXNodeType["documentType"] = 128] = "documentType"; })(GXNodeType || (GXNodeType = {})); class XMLReader extends xmlcommon_1.XMLBase { constructor() { // Internal variables super(...arguments); this.document = null; this.currentNodeInfo = { node: null, gxType: null }; /** * */ this.mSimpleElements = 1; } // Properties /** * Returns the name of the current element */ get name() { return this.currentNodeInfo.node ? this.currentNodeInfo.node.nodeName : ""; } /** * Returns the value of the current element */ get value() { return this.isSingleElementNode(this.currentNodeInfo.node) ? this.currentNodeInfo.node.textContent : ""; } /** * Returns the current node type obtained through the method Read or ReadType */ get nodeType() { return this.currentNodeInfo.gxType; } get eOF() { return this.mEOF ? 1 : 0; } /** * Indicates whether the current node obtained through the Read or ReadType method is simple */ get isSimple() { return this.isSingleElementNode(this.currentNodeInfo.node) ? 1 : 0; } /** * Returns the element's the namespace if it exists */ get prefix() { let prefix = ""; let components = this.name.split(":"); if (components.length === 2) { prefix = components[0]; } return prefix; } /** * Returns the name that represents the namespace, without indicating the prefix */ get localName() { let localName = ""; let components = this.name.split(":"); if (components.length === 2) { localName = components[1]; } else { localName = components[0]; } return localName; } get simpleElements() { return this.mSimpleElements; } set simpleElements(value) { this.mSimpleElements = value; } // Properties for node type constants /** * */ get elementType() { return GXNodeType.element; } /** * */ get endTagType() { return GXNodeType.endTag; } /** * */ get textType() { return GXNodeType.text; } /** * */ get commentType() { return GXNodeType.comment; } /** * */ get whiteSpaceType() { return GXNodeType.whiteSpace; } /** * */ get cDataType() { return GXNodeType.cdata; } /** * */ get processingInstructionType() { return GXNodeType.processingInstruction; } /** * */ get doctypeType() { return GXNodeType.documentType; } // Opening documents /** * Reads the XML document from the given string source * @param {string} source * @return number */ openFromString(source) { this.resetDocument(); this.resetErrors(); const parser = new DOMParser(); const hasError = false; const doc = parser.parseFromString(source, "application/xml"); if (doc.documentElement.tagName === "parsererror") { this.mErrCode = xmlcommon_1.XMLErrorCodes.open_file; this.mErrDescription = doc.documentElement.innerText; } this.document = hasError ? null : doc; this.mEOF = hasError; return 0; } /** * Closes the current reading session * @return {number} */ close() { this.resetDocument(); return 0; } // Reading /** * Used to obtain the different nodes of the open file, in a sequential manner. * @return {number} If a node is read, the value returned is greater than zero. Otherwise it returns zero. */ read() { if (!this.document) { this.mErrCode = xmlcommon_1.XMLErrorCodes.no_open_document; this.mErrDescription = "No open document"; } else if (!this.currentNodeInfo.node) { if (!this.eOF) { this.setCurrentNode(this.document.documentElement); } } else { const node = this.currentNodeInfo.node; const gxType = this.currentNodeInfo.gxType; if (gxType !== GXNodeType.endTag && node.childNodes.length > 0 && (!this.isSingleElementNode(node) || !this.simpleElements)) { this.setCurrentNode(node.firstChild); } else if (node.nextSibling) { this.setCurrentNode(node.nextSibling); } else if (node.parentNode && node.parentNode.nodeType !== 9 /* Document */) { this.setCurrentNode(node.parentNode, GXNodeType.endTag); } else { this.setCurrentNode(null); } } return this.currentNodeInfo.node ? 1 : 0; } /** * Moves forward to the following node, but only if constraints established are fulfilled * @param {number} nodeType Node types to consider * @param {string} name (Optional) Specifies the value for the name of the node to be read, as long as the node is Element or EndTag type * @return {number} If a node is read, the value returned is greater than zero. Otherwise it returns zero. */ readType(nodeType, name = undefined) { let ret = this.read(); while (ret > 0) { const currType = this.currentNodeInfo.gxType; if ((nodeType & currType) === currType && (!name || this.name === name)) { break; } ret = this.read(); } return ret; } /** * Allows obtaining flat XML text from the start of an element. * @return {string} The XML corresponding to the current node */ readRawXML() { let xml = ""; if (this.currentNodeInfo.gxType === GXNodeType.element) { xml = this.currentNodeInfo.node.outerHTML; this.skip(); } return xml; } /** * Allows skipping a full element with all its children/sons. * It is valid only for nodes of the Element type. * @return {number} */ skip() { if (this.currentNodeInfo.gxType === GXNodeType.element) { const node = this.currentNodeInfo.node; if (node.nextSibling) { this.setCurrentNode(node.nextSibling); } else if (node.parentNode && node.parentNode.nodeType !== 9 /* Document */) { this.setCurrentNode(node.parentNode, GXNodeType.endTag); } else { this.setCurrentNode(null); } } return this.currentNodeInfo.node ? 1 : 0; } // Attributes /** * Returns the number of attributes in the current node, obtained through the Read or ReadType methods */ get attributeCount() { const atts = this.getCurrentNodeAttributesList(); return atts.length; } /** * Returns the value of an attribute of the current node indicated by its name * @param {string} name The attribute's name * @return {string} The attribute's value in the current node */ getAttributeByName(name) { const atts = this.getCurrentNodeAttributesList(); for (const att of atts) { if (att.nodeName === name) { return att.nodeValue; } } return ""; } /** * Returns the value of an attribute of the current node indicated by its index * @param {number} index The search index * @return {string} The attribute's value in the current node */ getAttributeByIndex(index) { const atts = this.getCurrentNodeAttributesList(); if (index >= 0 && index < atts.length) { return atts[index].nodeValue; } return ""; } /** * Indicates if there is an attribute with the given name in the current node * @param {string} name The name of the attribute * @return {number} 1 if the attribute exists, 0 otherwise */ existsAttribute(name) { const atts = this.getCurrentNodeAttributesList(); for (const att of atts) { if (att.nodeName === name) { return 1; } } return 0; } /** * Returns the full name, including the namespace if it exists * @param {number} index * @return string */ getAttributeName(index) { const atts = this.getCurrentNodeAttributesList(); if (index >= 0 && index < atts.length) { return atts[index].nodeName; } return ""; } /** * Returns the attribute's the namespace if it exists * @param {number} index * @return string */ getAttributePrefix(index) { const attName = this.getAttributeName(index); let prefix = ""; if (attName !== "") { const components = attName.split(":"); if (components.length === 2) { prefix = components[0]; } } return prefix; } /** * Returns the name of the attribute, excluding the namespace if it exists * @param {number} index * @return string */ getAttributeLocalName(index) { const attName = this.getAttributeName(index); let localName = ""; if (attName !== "") { const components = attName.split(":"); localName = components.length === 2 ? components[1] : attName; } return localName; } // Private methods resetErrors() { this.mErrCode = xmlcommon_1.XMLErrorCodes.no_error; this.mErrDescription = ""; } resetDocument() { this.document = null; this.currentNodeInfo.node = null; this.currentNodeInfo.gxType = null; this.mEOF = true; } isSingleElementNode(node) { return (node && node.nodeType === 1 && node.childNodes.length === 1 && node.firstChild.childNodes.length === 0); } nodeTypeToGXNodeType(type) { switch (type) { case 1: // Element return GXNodeType.element; case 3: // Text return GXNodeType.text; case 4: // CDATA return GXNodeType.cdata; case 7: // ProcessingInstruction return GXNodeType.processingInstruction; case 8: // Comment return GXNodeType.comment; case 10: // DocumentType return GXNodeType.documentType; case 2: // Attr case 5: // EntityReference case 6: // Entity case 9: // Document case 11: // DocumentFragment case 12: // Notation default: return undefined; } } setCurrentNode(node, gxNodeType = undefined) { this.currentNodeInfo.node = node; if (node) { this.currentNodeInfo.gxType = gxNodeType ? gxNodeType : this.nodeTypeToGXNodeType(node.nodeType); } else { this.currentNodeInfo.gxType = null; } this.setEOFForCurrentNode(); } getCurrentNodeAttributesList() { const element = this.currentNodeInfo.node; if (!element) { return null; } return Array.from(element.attributes); } setEOFForCurrentNode() { const node = this.currentNodeInfo.node; if (node === null) { this.mEOF = true; } else { const gxType = this.currentNodeInfo.gxType; if ((gxType !== GXNodeType.endTag && node.childNodes.length > 0) || node.nextSibling || (node.parentNode && node.parentNode.nodeType !== 9) /* Document */) { this.mEOF = false; } else { this.mEOF = true; } } } // Not (yet) supported /** * @param {string} file * @return number */ open(file) { (0, helpers_1.notSupported)(); return null; } // =========================== // To check // =========================== /** * @param request * @return any */ openRequest(request) { (0, helpers_1.notImplemented)(); return null; } /** * @param client * @return any */ openResponse(client) { (0, helpers_1.notImplemented)(); return null; } /** * Returns the URI of the namespace if it exists * @param {number} index * @return string */ getAttributeURI(index) { (0, helpers_1.notImplemented)(); return null; } /** * @param index * @return any */ getAttEntityValueByIndex(index) { (0, helpers_1.notImplemented)(); return null; } /** * @param name * @return any */ getAttEntityValueByName(name) { (0, helpers_1.notImplemented)(); return null; } /** * @param index * @return any */ getAttEntityNotationByIndex(index) { (0, helpers_1.notImplemented)(); return null; } /** * @param name * @return any */ getAttEntityNotationByName(name) { (0, helpers_1.notImplemented)(); return null; } /** * @param encoding * @return any */ setDocEncoding(encoding) { (0, helpers_1.notImplemented)(); return null; } /** * @param encoding * @return any */ setNodeEncoding(encoding) { (0, helpers_1.notImplemented)(); return null; } /** * @param uri * @param namespace * @return any */ addSchema(uri, namespace) { (0, helpers_1.notImplemented)(); return null; } get errLineNumber() { return this.merrLineNumber; } get errLinePos() { return this.merrLinePos; } get nameSpaceURI() { return this.mnameSpaceURI; } get readExternalEntities() { return this.mreadExternalEntities; } set readExternalEntities(value) { this.mreadExternalEntities = value; } get removeWhiteSpaces() { return this.mremoveWhiteSpaces; } set removeWhiteSpaces(value) { this.mremoveWhiteSpaces = value; } get removeWhiteNodes() { return this.mremoveWhiteNodes; } set removeWhiteNodes(value) { this.mremoveWhiteNodes = value; } get linesNormalization() { return this.mlinesNormalization; } set linesNormalization(value) { this.mlinesNormalization = value; } get stopOnInvalid() { return this.mstopOnInvalid; } set stopOnInvalid(value) { this.mstopOnInvalid = value; } get validationType() { return this.mvalidationType; } set validationType(value) { this.mvalidationType = value; } } exports.XMLReader = XMLReader; //# sourceMappingURL=xmlreader.js.map