UNPKG

typesxml

Version:

Open source XML library written in TypeScript

111 lines 3.88 kB
"use strict"; /******************************************************************************* * Copyright (c) 2023 - 2024 Maxprograms. * * This program and the accompanying materials * are made available under the terms of the Eclipse License 1.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/org/documents/epl-v10.html * * Contributors: * Maxprograms - initial API and implementation *******************************************************************************/ Object.defineProperty(exports, "__esModule", { value: true }); exports.ContentModel = void 0; const Constants_1 = require("../Constants"); const XMLUtils_1 = require("../XMLUtils"); class ContentModel { OPTIONAL = '?'; ZERO_OR_MORE = '*'; ONE_OR_MORE = '+'; ONE = ''; grammar; name; mixed; contentTypes = ['EMPTY', 'ANY', 'MIXED', 'CHILDREN']; contentType; model; constructor(grammar, name, contentSpec) { this.grammar = grammar; this.name = name; this.model = this.parseSpec(contentSpec); this.mixed = false; } parseSpec(contentSpec) { let result = []; let tokens = []; let token = ''; let index = 0; while (index < contentSpec.length) { let c = contentSpec.charAt(index++); if (XMLUtils_1.XMLUtils.isXmlSpace(c)) { continue; } if (c === '*' || c === '+' || c === '?') { if (tokens.length < 1) { throw new Error('Invalid content model: ' + contentSpec); } tokens[tokens.length - 1] = tokens[tokens.length - 1] + c; } if (c === '(' || c === ')' || c === '|' || c === ',') { if (token.length > 0) { tokens.push(token); token = ''; } tokens.push(c); } else { token += c; } } return result; } toString() { return this.name; } isMixed() { return this.mixed; } isValid(element) { let attList = this.grammar.getElementAttributesMap(element.getName()); let attributes = element.getAttributes(); for (let i = 0; i < attributes.length; i++) { let attribute = attributes[i]; let name = attribute.getName(); let attDecl = attList.get(name); if (attDecl) { if (!attDecl.isValid(attribute.getValue())) { return false; } } else { throw new Error('Attribute \'' + name + '\' not allowed in element \'' + element.getName() + '\''); } } let content = element.getContent(); if (this.contentType === 'EMPTY' && content.length > 0) { throw new Error('Empty \'' + element.getName() + '\' element has content'); } if (this.contentType === 'ANY') { return true; } if (content) { for (let i = 0; i < content.length; i++) { let node = content[i]; if (node.getNodeType() === Constants_1.Constants.TEXT_NODE) { let text = node.toString(); if (text.trim().length > 0 && this.contentType !== 'MIXED') { throw new Error('Element \'' + element.getName() + '\' cannot have #PCDATA content'); } } if (node.getNodeType() === Constants_1.Constants.ELEMENT_NODE) { let childElement = node; // TODO check sequence } } } return true; } } exports.ContentModel = ContentModel; //# sourceMappingURL=ContentModel.js.map