UNPKG

typesxml

Version:

Open source XML library written in TypeScript

128 lines 5.27 kB
/******************************************************************************* * Copyright (c) 2023-2026 Maxprograms. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public 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 *******************************************************************************/ import { ValidationResult } from '../grammar/Grammar.js'; import { SchemaAll } from './SchemaAll.js'; import { SchemaChoice } from './SchemaChoice.js'; import { SchemaSequence } from './SchemaSequence.js'; import { SchemaWildcardParticle } from './SchemaWildcardParticle.js'; export var SchemaContentModelType; (function (SchemaContentModelType) { SchemaContentModelType["EMPTY"] = "EMPTY"; SchemaContentModelType["ANY"] = "ANY"; SchemaContentModelType["MIXED"] = "MIXED"; SchemaContentModelType["ELEMENT"] = "ELEMENT"; })(SchemaContentModelType || (SchemaContentModelType = {})); export class SchemaContentModel { type; rootParticle; constructor(type, rootParticle) { this.type = type; this.rootParticle = rootParticle; } getType() { return this.type; } getRootParticle() { return this.rootParticle; } static empty() { return new SchemaContentModel(SchemaContentModelType.EMPTY); } static any() { return new SchemaContentModel(SchemaContentModelType.ANY); } static mixed(rootParticle) { return new SchemaContentModel(SchemaContentModelType.MIXED, rootParticle); } static element(rootParticle) { return new SchemaContentModel(SchemaContentModelType.ELEMENT, rootParticle); } hasAnyWildcard() { if (!this.rootParticle) { return false; } return SchemaContentModel.particleHasWildcard(this.rootParticle); } static particleHasWildcard(particle) { if (particle instanceof SchemaWildcardParticle) { return true; } if (particle instanceof SchemaSequence || particle instanceof SchemaChoice || particle instanceof SchemaAll) { for (const child of particle.particles) { if (SchemaContentModel.particleHasWildcard(child)) { return true; } } } return false; } findCoveringWildcard(childName, nsMap) { if (!this.rootParticle) { return undefined; } return SchemaContentModel.walkParticleForWildcard(this.rootParticle, childName, nsMap); } static walkParticleForWildcard(particle, childName, nsMap) { if (particle instanceof SchemaWildcardParticle) { const matched = particle.matchOnce([childName], 0, nsMap); if (matched.length > 0) { return particle.processContents; } return undefined; } if (particle instanceof SchemaSequence || particle instanceof SchemaChoice || particle instanceof SchemaAll) { for (const child of particle.particles) { const result = SchemaContentModel.walkParticleForWildcard(child, childName, nsMap); if (result !== undefined) { return result; } } } return undefined; } validateChildren(elementName, children, nsMap, childNamespaces) { if (this.type === SchemaContentModelType.EMPTY) { if (children.length > 0) { return ValidationResult.error('Element "' + elementName + '" must be empty but contains child elements: ' + children.join(', ')); } return ValidationResult.success(); } if (this.type === SchemaContentModelType.ANY) { return ValidationResult.success(); } // MIXED: child elements must conform to the declared particle when one exists. // If no particle is present, any children are allowed. if (this.type === SchemaContentModelType.MIXED) { if (!this.rootParticle) { return ValidationResult.success(); } } if (!this.rootParticle) { // ELEMENT type with no particle — treat as EMPTY. if (children.length > 0) { return ValidationResult.error('Element "' + elementName + '" has no content model but contains child elements: ' + children.join(', ')); } return ValidationResult.success(); } // Run the NFA: success when the root particle's matchRepeated can reach // exactly children.length (all children consumed). const positions = this.rootParticle.matchRepeated(children, 0, nsMap, childNamespaces); for (const p of positions) { if (p === children.length) { return ValidationResult.success(); } } return ValidationResult.error('Element "' + elementName + '" has an invalid child element sequence. ' + 'Children found: [' + children.join(', ') + ']'); } } //# sourceMappingURL=SchemaContentModel.js.map