@genexus/web-standard-functions
Version:
GeneXus JavaScript standard functions library for web generators
563 lines • 16 kB
JavaScript
"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