typesxml
Version:
Open source XML library written in TypeScript
788 lines • 33.9 kB
JavaScript
"use strict";
/*******************************************************************************
* Copyright (c) 2023-2026 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.XMLSchemaParser = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const node_url_1 = require("node:url");
const Constants_js_1 = require("./Constants.js");
const DOMBuilder_js_1 = require("./DOMBuilder.js");
const SAXParser_js_1 = require("./SAXParser.js");
const XMLAttribute_js_1 = require("./XMLAttribute.js");
const XMLElement_js_1 = require("./XMLElement.js");
const XSDSemanticValidator_js_1 = require("./schema/XSDSemanticValidator.js");
class XMLSchemaParser {
static instance;
static XML_NS = 'http://www.w3.org/XML/1998/namespace';
static IGNORED_NAMESPACES = new Set([
Constants_js_1.Constants.XML_SCHEMA_INSTANCE_NS_URI
]);
catalog;
schemaCache;
schemaProcessingStack;
visitedSchemas;
complexTypeDefinitions;
redefineOriginals;
attributeGroupDefinitions;
attributeDefinitions;
elementDefinitions;
simpleTypeDefinitions;
collectedDefaults;
complexTypeDefaultCache;
attributeGroupDefaultCache;
parsedSchemaRoots;
constructor(catalog) {
this.catalog = catalog;
this.schemaCache = new Map();
this.schemaProcessingStack = new Set();
this.visitedSchemas = new Set();
this.complexTypeDefinitions = new Map();
this.redefineOriginals = new Map();
this.attributeGroupDefinitions = new Map();
this.attributeDefinitions = new Map();
this.elementDefinitions = new Map();
this.simpleTypeDefinitions = new Map();
this.collectedDefaults = new Map();
this.complexTypeDefaultCache = new Map();
this.attributeGroupDefaultCache = new Map();
this.parsedSchemaRoots = [];
}
static getInstance(catalog) {
if (!XMLSchemaParser.instance) {
XMLSchemaParser.instance = new XMLSchemaParser(catalog);
}
else if (catalog) {
XMLSchemaParser.instance.catalog = catalog;
}
return XMLSchemaParser.instance;
}
collectDefaultAttributes(schemaPath) {
const normalizedPath = this.normalizePath(schemaPath);
const cached = this.schemaCache.get(normalizedPath);
if (cached) {
return this.cloneDefaults(cached);
}
if (this.schemaProcessingStack.has(normalizedPath)) {
return new Map();
}
this.schemaProcessingStack.add(normalizedPath);
try {
this.resetWorkingState();
this.walkSchema(normalizedPath);
this.elementDefinitions.forEach((info, key) => {
const defaults = this.computeDefaultsForElement(info);
if (defaults.size === 0) {
return;
}
this.collectedDefaults.set(key, this.cloneAttributeDefaultMap(defaults));
if (!this.collectedDefaults.has(info.localName)) {
this.collectedDefaults.set(info.localName, this.cloneAttributeDefaultMap(defaults));
}
});
const snapshot = this.cloneDefaults(this.collectedDefaults);
this.schemaCache.set(normalizedPath, snapshot);
return this.cloneDefaults(snapshot);
}
finally {
this.schemaProcessingStack.delete(normalizedPath);
}
}
resetWorkingState() {
this.visitedSchemas = new Set();
this.complexTypeDefinitions = new Map();
this.redefineOriginals = new Map();
this.attributeGroupDefinitions = new Map();
this.attributeDefinitions = new Map();
this.elementDefinitions = new Map();
this.simpleTypeDefinitions = new Map();
this.collectedDefaults = new Map();
this.complexTypeDefaultCache = new Map();
this.attributeGroupDefaultCache = new Map();
this.parsedSchemaRoots = [];
this.injectXmlNamespaceAttributes();
}
injectXmlNamespaceAttributes() {
const xmlAttrs = [
['lang', 'xs:language'],
['space', 'xs:NCName'],
['base', 'xs:anyURI'],
['id', 'xs:ID']
];
for (const [localName, type] of xmlAttrs) {
const el = new XMLElement_js_1.XMLElement('xs:attribute');
el.setAttribute(new XMLAttribute_js_1.XMLAttribute('name', localName));
el.setAttribute(new XMLAttribute_js_1.XMLAttribute('type', type));
const info = { element: el, namespace: XMLSchemaParser.XML_NS };
const key = XMLSchemaParser.XML_NS + '|' + localName;
this.attributeDefinitions.set(key, info);
this.attributeDefinitions.set('xml:' + localName, info);
}
}
cloneDefaults(source) {
const clone = new Map();
source.forEach((value, key) => {
clone.set(key, this.cloneAttributeDefaultMap(value));
});
return clone;
}
cloneAttributeDefaultMap(source) {
const clone = new Map();
source.forEach((value, key) => {
const copy = {
localName: value.localName,
namespace: value.namespace,
lexicalName: value.lexicalName,
value: value.value
};
clone.set(key, copy);
});
return clone;
}
computeDefaultsForElement(info) {
const cacheKey = this.buildElementKey(info.localName, info.namespace);
if (this.collectedDefaults.has(cacheKey)) {
const cached = this.collectedDefaults.get(cacheKey);
return cached ? this.cloneAttributeDefaultMap(cached) : new Map();
}
const accumulator = new Map();
const visitedTypes = new Set();
this.collectDefaultsFromElementDeclaration(info.element, accumulator, visitedTypes, info.namespace);
return accumulator;
}
collectDefaultsFromElementDeclaration(element, accumulator, visitedTypes, namespace) {
const children = element.getChildren();
for (let index = 0; index < children.length; index++) {
const child = children[index];
const localName = this.getLocalName(child.getName());
if (localName === "complexType") {
this.collectDefaultsFromComplexType(child, accumulator, visitedTypes, namespace);
}
if (localName === "defaultAttributes") {
// XML Schema 1.1 defaultAttributes on elements
this.collectDefaultsFromAttributeContainer(child, accumulator, visitedTypes, namespace);
}
}
const typeAttr = element.getAttribute("type");
if (typeAttr) {
const defaults = this.resolveTypeDefaults(typeAttr.getValue(), namespace, visitedTypes);
this.mergeMaps(accumulator, defaults);
}
}
collectDefaultsFromComplexType(typeElement, accumulator, visitedTypes, namespace) {
const nameAttribute = typeElement.getAttribute("name");
if (nameAttribute) {
const typeKey = this.buildTypeKey(nameAttribute.getValue(), namespace);
if (visitedTypes.has(typeKey)) {
return;
}
visitedTypes.add(typeKey);
}
this.collectDefaultsFromAttributeContainer(typeElement, accumulator, visitedTypes, namespace);
}
collectDefaultsFromAttributeContainer(container, accumulator, visitedTypes, namespace) {
const children = container.getChildren();
for (let index = 0; index < children.length; index++) {
const child = children[index];
const localName = this.getLocalName(child.getName());
if (localName === "attribute") {
this.recordAttributeDefault(child, accumulator, namespace);
continue;
}
if (localName === "attributeGroup") {
const refAttribute = child.getAttribute("ref");
if (!refAttribute) {
continue;
}
const groupDefaults = this.resolveAttributeGroupDefaults(refAttribute.getValue(), namespace);
this.mergeMaps(accumulator, groupDefaults);
continue;
}
if (localName === "defaultAttributes") {
// XML Schema 1.1 defaultAttributes - collect from child attributes/attributeGroups
this.collectDefaultsFromAttributeContainer(child, accumulator, visitedTypes, namespace);
continue;
}
// XML Schema 1.1 schema-level defaultAttributes/defaultAttributesApply not yet supported; can be added when real schemas require it.
if (localName === "complexContent" || localName === "simpleContent") {
this.collectDefaultsFromAttributeContainer(child, accumulator, visitedTypes, namespace);
continue;
}
if (localName === "extension" || localName === "restriction") {
const baseAttribute = child.getAttribute("base");
if (baseAttribute) {
const baseDefaults = this.resolveTypeDefaults(baseAttribute.getValue(), namespace, visitedTypes);
this.mergeMaps(accumulator, baseDefaults);
}
this.collectDefaultsFromAttributeContainer(child, accumulator, visitedTypes, namespace);
continue;
}
if (localName === "complexType") {
this.collectDefaultsFromComplexType(child, accumulator, visitedTypes, namespace);
}
}
}
recordAttributeDefault(attributeElement, accumulator, namespace) {
const defaultAttribute = attributeElement.getAttribute("default");
const fixedAttribute = attributeElement.getAttribute("fixed");
let valueAttribute = defaultAttribute ?? fixedAttribute;
const nameAttribute = attributeElement.getAttribute("name");
const refAttribute = attributeElement.getAttribute("ref");
const useAttribute = attributeElement.getAttribute("use");
const referencedDefinition = refAttribute ? this.lookupAttribute(refAttribute.getValue(), namespace) : undefined;
const referencedElement = referencedDefinition ? referencedDefinition.element : undefined;
let attributeNamespace = referencedDefinition ? referencedDefinition.namespace : undefined;
let lexicalName = undefined;
let attributeLocalName = undefined;
if (refAttribute) {
lexicalName = refAttribute.getValue();
attributeLocalName = this.getLocalName(lexicalName);
}
else if (nameAttribute) {
attributeLocalName = nameAttribute.getValue();
lexicalName = attributeLocalName;
}
if (!attributeLocalName && referencedElement) {
const referencedName = referencedElement.getAttribute("name");
if (referencedName) {
attributeLocalName = referencedName.getValue();
lexicalName = referencedName.getValue();
}
}
if (!attributeNamespace) {
const formAttribute = attributeElement.getAttribute("form");
if (formAttribute && formAttribute.getValue() === "qualified") {
attributeNamespace = namespace;
}
}
if (!lexicalName && attributeLocalName) {
lexicalName = attributeLocalName;
}
if (!attributeLocalName) {
return;
}
if (useAttribute && useAttribute.getValue() === "prohibited") {
const prohibitedKey = this.buildAttributeKey(attributeLocalName, attributeNamespace);
accumulator.delete(prohibitedKey);
if (attributeNamespace) {
accumulator.delete(attributeLocalName);
}
return;
}
if (!valueAttribute && referencedElement) {
const referencedFixed = referencedElement.getAttribute("fixed");
const referencedDefault = referencedElement.getAttribute("default");
valueAttribute = referencedDefault ?? referencedFixed ?? undefined;
}
if (!valueAttribute) {
return;
}
const defaultInfo = {
localName: attributeLocalName,
namespace: attributeNamespace,
lexicalName: lexicalName ?? attributeLocalName,
value: valueAttribute.getValue()
};
this.setAttributeDefault(accumulator, defaultInfo);
}
resolveTypeDefaults(typeName, namespace, visitedTypes) {
const localName = this.getLocalName(typeName);
const key = this.buildTypeKey(localName, namespace);
const cached = this.complexTypeDefaultCache.get(key);
if (cached) {
return this.cloneAttributeDefaultMap(cached);
}
const definition = this.lookupComplexType(typeName);
if (!definition) {
return new Map();
}
const visited = visitedTypes ? new Set(visitedTypes) : new Set();
if (visited.has(key)) {
return new Map();
}
const accumulator = new Map();
this.collectDefaultsFromComplexType(definition, accumulator, visited, namespace);
this.complexTypeDefaultCache.set(key, this.cloneAttributeDefaultMap(accumulator));
return accumulator;
}
resolveAttributeGroupDefaults(groupName, namespace, visitedGroups) {
const localName = this.getLocalName(groupName);
const key = this.buildTypeKey(localName, namespace);
const cached = this.attributeGroupDefaultCache.get(key);
if (cached) {
return this.cloneAttributeDefaultMap(cached);
}
const definition = this.lookupAttributeGroup(groupName);
if (!definition) {
return new Map();
}
const visited = visitedGroups ? new Set(visitedGroups) : new Set();
if (visited.has(key)) {
return new Map();
}
visited.add(key);
const accumulator = new Map();
const children = definition.getChildren();
for (let index = 0; index < children.length; index++) {
const child = children[index];
const childLocalName = this.getLocalName(child.getName());
if (childLocalName === "attribute") {
this.recordAttributeDefault(child, accumulator, namespace);
continue;
}
if (childLocalName === "attributeGroup") {
const refAttribute = child.getAttribute("ref");
if (!refAttribute) {
continue;
}
const nestedDefaults = this.resolveAttributeGroupDefaults(refAttribute.getValue(), namespace, visited);
this.mergeMaps(accumulator, nestedDefaults);
}
}
this.attributeGroupDefaultCache.set(key, this.cloneAttributeDefaultMap(accumulator));
return accumulator;
}
lookupComplexType(typeName) {
const direct = this.complexTypeDefinitions.get(typeName);
if (direct) {
return direct;
}
const localName = this.getLocalName(typeName);
const byLocal = this.complexTypeDefinitions.get(localName);
if (byLocal) {
return byLocal;
}
const entries = Array.from(this.complexTypeDefinitions.entries());
for (let index = 0; index < entries.length; index++) {
const entry = entries[index];
const candidateKey = entry[0];
if (candidateKey.endsWith("|" + localName) || candidateKey === localName) {
return entry[1];
}
}
return undefined;
}
lookupOriginalComplexType(typeName) {
const localName = this.getLocalName(typeName);
return this.redefineOriginals.get(typeName) ?? this.redefineOriginals.get(localName);
}
lookupAttributeGroup(groupName) {
const direct = this.attributeGroupDefinitions.get(groupName);
if (direct) {
return direct;
}
const localName = this.getLocalName(groupName);
const byLocal = this.attributeGroupDefinitions.get(localName);
if (byLocal) {
return byLocal;
}
const entries = Array.from(this.attributeGroupDefinitions.entries());
for (let index = 0; index < entries.length; index++) {
const entry = entries[index];
const candidateKey = entry[0];
if (candidateKey.endsWith("|" + localName) || candidateKey === localName) {
return entry[1];
}
}
return undefined;
}
lookupAttributeGroupWithNamespace(groupName) {
const localName = this.getLocalName(groupName);
const entries = Array.from(this.attributeGroupDefinitions.entries());
for (const entry of entries) {
const key = entry[0];
const pipeIdx = key.lastIndexOf('|');
if (pipeIdx !== -1 && key.substring(pipeIdx + 1) === localName) {
const ns = key.substring(0, pipeIdx);
return { element: entry[1], namespace: ns.length > 0 ? ns : undefined };
}
}
const direct = this.attributeGroupDefinitions.get(groupName);
if (direct) {
return { element: direct, namespace: undefined };
}
const byLocal = this.attributeGroupDefinitions.get(localName);
if (byLocal) {
return { element: byLocal, namespace: undefined };
}
return undefined;
}
lookupComplexTypeWithNamespace(typeName) {
const localName = this.getLocalName(typeName);
const entries = Array.from(this.complexTypeDefinitions.entries());
for (const entry of entries) {
const key = entry[0];
const pipeIdx = key.lastIndexOf('|');
if (pipeIdx !== -1 && key.substring(pipeIdx + 1) === localName) {
const ns = key.substring(0, pipeIdx);
return { element: entry[1], namespace: ns.length > 0 ? ns : undefined };
}
}
const direct = this.complexTypeDefinitions.get(typeName);
if (direct) {
return { element: direct, namespace: undefined };
}
const byLocal = this.complexTypeDefinitions.get(localName);
if (byLocal) {
return { element: byLocal, namespace: undefined };
}
return undefined;
}
lookupAttribute(name, namespace) {
const direct = this.attributeDefinitions.get(name);
if (direct) {
return direct;
}
const localName = this.getLocalName(name);
const namespacedKey = this.buildAttributeKey(localName, namespace);
const byNamespace = this.attributeDefinitions.get(namespacedKey);
if (byNamespace) {
return byNamespace;
}
const byLocal = this.attributeDefinitions.get(localName);
if (byLocal) {
return byLocal;
}
const entries = Array.from(this.attributeDefinitions.entries());
for (let index = 0; index < entries.length; index++) {
const entry = entries[index];
const candidateKey = entry[0];
if (candidateKey.endsWith("|" + localName) || candidateKey === localName) {
return entry[1];
}
}
return undefined;
}
mergeMaps(target, source) {
source.forEach((value) => {
this.setAttributeDefault(target, value);
});
}
walkSchema(schemaPath, includingTargetNamespace) {
const normalizedPath = this.normalizePath(schemaPath);
if (this.visitedSchemas.has(normalizedPath)) {
return;
}
if (!(0, node_fs_1.existsSync)(normalizedPath)) {
throw new Error(`XML Schema file not found: ${schemaPath}`);
}
this.visitedSchemas.add(normalizedPath);
const domBuilder = new DOMBuilder_js_1.DOMBuilder();
const parser = new SAXParser_js_1.SAXParser();
if (this.catalog) {
parser.setCatalog(this.catalog);
}
parser.setSchemaLoadingEnabled(false);
parser.setContentHandler(domBuilder);
parser.parseFile(normalizedPath);
const document = domBuilder.getDocument();
if (!document) {
return;
}
const root = document.getRoot();
if (!root) {
return;
}
const targetNamespaceAttribute = root.getAttribute("targetNamespace");
const targetNamespace = targetNamespaceAttribute ? targetNamespaceAttribute.getValue() : undefined;
if (includingTargetNamespace !== undefined) {
XSDSemanticValidator_js_1.XSDSemanticValidator.checkIncludedNamespace(root, includingTargetNamespace !== null ? includingTargetNamespace : undefined);
}
this.parsedSchemaRoots.push(root);
this.registerSchemaComponents(root, targetNamespace);
this.processSchemaReferences(root, (0, node_path_1.dirname)(normalizedPath));
}
processSchemaReferences(schemaElement, baseDir) {
const children = schemaElement.getChildren();
for (let index = 0; index < children.length; index++) {
const child = children[index];
const localName = this.getLocalName(child.getName());
if (localName !== "include" && localName !== "import" && localName !== "redefine") {
continue;
}
const locationAttribute = child.getAttribute("schemaLocation");
const namespaceAttribute = child.getAttribute("namespace");
const location = locationAttribute ? locationAttribute.getValue() : undefined;
const namespaceValue = namespaceAttribute ? namespaceAttribute.getValue() : undefined;
if (namespaceValue && XMLSchemaParser.shouldIgnoreNamespace(namespaceValue)) {
continue;
}
const resolved = this.resolveReference(location, baseDir, namespaceValue);
if (resolved) {
if (localName === 'include') {
const includingNsAttr = schemaElement.getAttribute('targetNamespace');
this.walkSchema(resolved, includingNsAttr !== undefined ? includingNsAttr.getValue() : null);
}
else {
this.walkSchema(resolved);
}
}
// For xs:redefine, after loading the base schema apply the redefined components (force-overwrite).
if (localName === 'redefine') {
const targetNsAttr = schemaElement.getAttribute('targetNamespace');
const targetNamespace = targetNsAttr ? targetNsAttr.getValue() : undefined;
this.applyRedefinitions(child, targetNamespace);
}
}
}
applyRedefinitions(redefineElement, targetNamespace) {
for (const child of redefineElement.getChildren()) {
const localName = this.getLocalName(child.getName());
if (localName === 'complexType') {
const nameAttr = child.getAttribute('name');
if (!nameAttr) {
continue;
}
const typeName = nameAttr.getValue();
const nsKey = this.buildTypeKey(typeName, targetNamespace);
const localKey = this.getLocalName(typeName);
// Save the original before overwriting so self-extension can resolve it.
const original = this.complexTypeDefinitions.get(nsKey)
?? this.complexTypeDefinitions.get(typeName)
?? this.complexTypeDefinitions.get(localKey);
if (original) {
this.redefineOriginals.set(typeName, original);
this.redefineOriginals.set(nsKey, original);
this.redefineOriginals.set(localKey, original);
}
// Force-overwrite with the redefined version.
this.complexTypeDefinitions.set(nsKey, child);
this.complexTypeDefinitions.set(typeName, child);
this.complexTypeDefinitions.set(localKey, child);
}
if (localName === 'simpleType') {
const nameAttr = child.getAttribute('name');
if (!nameAttr) {
continue;
}
const typeName = nameAttr.getValue();
const nsKey = this.buildTypeKey(typeName, targetNamespace);
this.simpleTypeDefinitions.set(typeName, child);
this.simpleTypeDefinitions.set(nsKey, child);
}
}
}
static shouldIgnoreNamespace(namespaceUri) {
return XMLSchemaParser.IGNORED_NAMESPACES.has(namespaceUri);
}
registerSchemaComponents(schemaElement, targetNamespace) {
const children = schemaElement.getChildren();
for (let index = 0; index < children.length; index++) {
const child = children[index];
const localName = this.getLocalName(child.getName());
if (localName === "element") {
const nameAttribute = child.getAttribute("name");
if (!nameAttribute) {
continue;
}
const elementName = nameAttribute.getValue();
const key = this.buildElementKey(elementName, targetNamespace);
if (!this.elementDefinitions.has(key)) {
const info = {
element: child,
namespace: targetNamespace,
localName: elementName
};
this.elementDefinitions.set(key, info);
}
continue;
}
if (localName === "complexType") {
const nameAttribute = child.getAttribute("name");
if (!nameAttribute) {
continue;
}
const typeName = nameAttribute.getValue();
const key = this.buildTypeKey(typeName, targetNamespace);
if (!this.complexTypeDefinitions.has(key)) {
this.complexTypeDefinitions.set(key, child);
}
if (!this.complexTypeDefinitions.has(typeName)) {
this.complexTypeDefinitions.set(typeName, child);
}
const localKey = this.getLocalName(typeName);
if (!this.complexTypeDefinitions.has(localKey)) {
this.complexTypeDefinitions.set(localKey, child);
}
continue;
}
if (localName === "attributeGroup") {
const nameAttribute = child.getAttribute("name");
if (!nameAttribute) {
continue;
}
const groupName = nameAttribute.getValue();
const key = this.buildTypeKey(groupName, targetNamespace);
if (!this.attributeGroupDefinitions.has(key)) {
this.attributeGroupDefinitions.set(key, child);
}
if (!this.attributeGroupDefinitions.has(groupName)) {
this.attributeGroupDefinitions.set(groupName, child);
}
const localKey = this.getLocalName(groupName);
if (!this.attributeGroupDefinitions.has(localKey)) {
this.attributeGroupDefinitions.set(localKey, child);
}
continue;
}
if (localName === "attribute") {
const nameAttribute = child.getAttribute("name");
if (!nameAttribute) {
continue;
}
const attributeName = nameAttribute.getValue();
const key = this.buildAttributeKey(attributeName, targetNamespace);
const info = {
element: child,
namespace: targetNamespace
};
if (!this.attributeDefinitions.has(key)) {
this.attributeDefinitions.set(key, info);
}
if (!this.attributeDefinitions.has(attributeName)) {
this.attributeDefinitions.set(attributeName, info);
}
const localKey = this.getLocalName(attributeName);
if (!this.attributeDefinitions.has(localKey)) {
this.attributeDefinitions.set(localKey, info);
}
continue;
}
if (localName === "simpleType") {
const nameAttribute = child.getAttribute("name");
if (!nameAttribute) {
continue;
}
const typeName = nameAttribute.getValue();
if (!this.simpleTypeDefinitions.has(typeName)) {
this.simpleTypeDefinitions.set(typeName, child);
}
if (targetNamespace) {
const nsKey = targetNamespace + '|' + typeName;
if (!this.simpleTypeDefinitions.has(nsKey)) {
this.simpleTypeDefinitions.set(nsKey, child);
}
}
}
}
}
resolveReference(location, baseDir, namespaceValue) {
if (this.catalog) {
const candidates = [];
if (location) {
candidates.push(this.catalog.matchURI(location));
candidates.push(this.catalog.matchSystem(location));
}
if (namespaceValue) {
candidates.push(this.catalog.matchURI(namespaceValue));
candidates.push(this.catalog.matchSystem(namespaceValue));
}
for (const candidate of candidates) {
if (!candidate) {
continue;
}
const normalizedCandidate = candidate.startsWith("file://") ? (0, node_url_1.fileURLToPath)(candidate) : candidate;
if ((0, node_fs_1.existsSync)(normalizedCandidate)) {
return normalizedCandidate;
}
}
}
if (!location) {
return undefined;
}
if (location.startsWith("http://") || location.startsWith("https://")) {
return undefined;
}
if (location.startsWith("file://")) {
const normalizedFileUrl = (0, node_url_1.fileURLToPath)(location);
if ((0, node_fs_1.existsSync)(normalizedFileUrl)) {
return normalizedFileUrl;
}
return undefined;
}
if ((0, node_path_1.isAbsolute)(location)) {
if ((0, node_fs_1.existsSync)(location)) {
return location;
}
return undefined;
}
const resolvedPath = (0, node_path_1.resolve)(baseDir, location);
if ((0, node_fs_1.existsSync)(resolvedPath)) {
return resolvedPath;
}
return undefined;
}
normalizePath(location) {
if (location.startsWith("file://")) {
return (0, node_url_1.fileURLToPath)(location);
}
if ((0, node_path_1.isAbsolute)(location)) {
return location;
}
return (0, node_path_1.resolve)(location);
}
getLocalName(name) {
const separatorIndex = name.indexOf(":");
if (separatorIndex === -1) {
return name;
}
return name.substring(separatorIndex + 1);
}
buildElementKey(name, namespace) {
if (namespace) {
return `${namespace}|${name}`;
}
return name;
}
buildTypeKey(name, namespace) {
const localName = this.getLocalName(name);
if (namespace) {
return `${namespace}|${localName}`;
}
return localName;
}
buildAttributeKey(name, namespace) {
const localName = this.getLocalName(name);
if (namespace) {
return namespace + "|" + localName;
}
return localName;
}
setAttributeDefault(target, value) {
const key = this.buildAttributeKey(value.localName, value.namespace);
const keysToRemove = [];
target.forEach((existing, existingKey) => {
if (existing.localName !== value.localName) {
return;
}
const sameNamespace = existing.namespace === value.namespace;
if (sameNamespace && existingKey === key) {
return;
}
if (sameNamespace || (value.namespace && !existing.namespace)) {
keysToRemove.push(existingKey);
}
});
for (let index = 0; index < keysToRemove.length; index++) {
target.delete(keysToRemove[index]);
}
const stored = {
localName: value.localName,
namespace: value.namespace,
lexicalName: value.lexicalName,
value: value.value
};
target.set(key, stored);
}
}
exports.XMLSchemaParser = XMLSchemaParser;
//# sourceMappingURL=XMLSchemaParser.js.map