typesxml
Version:
Open source XML library written in TypeScript
132 lines • 5.77 kB
JavaScript
;
/*******************************************************************************
* 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
*******************************************************************************/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SchemaContentModel = exports.SchemaContentModelType = void 0;
const Grammar_js_1 = require("../grammar/Grammar.js");
const SchemaAll_js_1 = require("./SchemaAll.js");
const SchemaChoice_js_1 = require("./SchemaChoice.js");
const SchemaSequence_js_1 = require("./SchemaSequence.js");
const SchemaWildcardParticle_js_1 = require("./SchemaWildcardParticle.js");
var SchemaContentModelType;
(function (SchemaContentModelType) {
SchemaContentModelType["EMPTY"] = "EMPTY";
SchemaContentModelType["ANY"] = "ANY";
SchemaContentModelType["MIXED"] = "MIXED";
SchemaContentModelType["ELEMENT"] = "ELEMENT";
})(SchemaContentModelType || (exports.SchemaContentModelType = SchemaContentModelType = {}));
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_js_1.SchemaWildcardParticle) {
return true;
}
if (particle instanceof SchemaSequence_js_1.SchemaSequence || particle instanceof SchemaChoice_js_1.SchemaChoice || particle instanceof SchemaAll_js_1.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_js_1.SchemaWildcardParticle) {
const matched = particle.matchOnce([childName], 0, nsMap);
if (matched.length > 0) {
return particle.processContents;
}
return undefined;
}
if (particle instanceof SchemaSequence_js_1.SchemaSequence || particle instanceof SchemaChoice_js_1.SchemaChoice || particle instanceof SchemaAll_js_1.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 Grammar_js_1.ValidationResult.error('Element "' + elementName + '" must be empty but contains child elements: ' + children.join(', '));
}
return Grammar_js_1.ValidationResult.success();
}
if (this.type === SchemaContentModelType.ANY) {
return Grammar_js_1.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 Grammar_js_1.ValidationResult.success();
}
}
if (!this.rootParticle) {
// ELEMENT type with no particle — treat as EMPTY.
if (children.length > 0) {
return Grammar_js_1.ValidationResult.error('Element "' + elementName + '" has no content model but contains child elements: ' + children.join(', '));
}
return Grammar_js_1.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 Grammar_js_1.ValidationResult.success();
}
}
return Grammar_js_1.ValidationResult.error('Element "' + elementName + '" has an invalid child element sequence. ' +
'Children found: [' + children.join(', ') + ']');
}
}
exports.SchemaContentModel = SchemaContentModel;
//# sourceMappingURL=SchemaContentModel.js.map