UNPKG

salve-annos

Version:

A fork with support for documentation of Salve, a Javascript library which implements a validator able to validate an XML document on the basis of a subset of RelaxNG.

204 lines 8.57 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.DatatypeProcessor = void 0; exports.localName = localName; exports.fromQNameToURI = fromQNameToURI; const datatypes = __importStar(require("../../datatypes")); const patterns_1 = require("../../patterns"); const parser_1 = require("../parser"); const warnAboutTheseTypes = [ "ENTITY", "ENTITIES", ]; /** * @private * * @param el Element to start the search from. * * @returns ``true`` if ``el`` is an attribute or is in an RNG * ``<attribute>`` element. ``false`` otherwise. */ function inAttribute(el) { let current = el; while (current !== undefined) { if (current.local === "attribute") { return true; } current = current.parent; } return false; } function localName(value) { const sep = value.indexOf(":"); return (sep === -1) ? value : value.slice(sep + 1); } function fromQNameToURI(value, el) { const colon = value.indexOf(":"); let prefix; if (colon === -1) { // If there is no prefix if (inAttribute(el)) { // Attribute in undefined namespace return ""; } // We are searching for the default namespace currently in effect. prefix = ""; } else { prefix = value.substr(0, colon); if (value.lastIndexOf(":") !== colon) { throw new Error("invalid name"); } } if (prefix === "") { // Yes, we return the empty string even if that what @ns is set to: // there is no default namespace when @ns is set to ''. return el.mustGetAttribute("ns"); } // // We have a prefix, in which case @ns is useless. We have to get the // namespace from the namespaces declared in the XML file that contains the // schema. At this stage, @xmlns and @xmlns:prefix attributes should no longer // be available available. So we just ask the element to use its internal // namespace data to resolve the prefix. // // (Note: in fact in the current implementation of the simplifiers the xmlns // nodes are still available. The XSLT simplifier *cannot* carry the namespace // information we need without keeping those nodes around, or producing a // workaround. The internal simplifier does the same thing as the XSLT // simplifier for ease of debugging (we can expect the same results from // both). However... in any case the information is available through the // namespace information stored on the nodes. So...) // const uri = el.resolve(prefix); if (uri === undefined) { throw new Error(`cannot resolve prefix: ${prefix}`); } return uri; } /** * This walker checks that the types used in the tree can be used, and does * special processing for ``QName`` and ``NOTATION``. */ class DatatypeProcessor { constructor() { /** * The warnings generated during the walk. This array is populated while * walking. */ this.warnings = []; } // tslint:disable-next-line:max-func-body-length walk(el) { let libname; let type; // tslint:disable-line: no-reserved-keywords const name = el.local; switch (name) { case "value": { let value = el.text; type = el.mustGetAttribute("type"); libname = el.mustGetAttribute("datatypeLibrary"); let ns = el.mustGetAttribute("ns"); const lib = datatypes.registry.find(libname); if (lib === undefined) { throw new datatypes.ValueValidationError(el.path, [new datatypes.ValueError(`unknown datatype library: ${libname}`)]); } const datatype = lib.types[type]; if (datatype === undefined) { throw new datatypes.ValueValidationError(el.path, [new datatypes.ValueError(`unknown datatype ${type} in \ ${(libname === "") ? "default library" : `library ${libname}`}`)]); } if (datatype.needsContext && // tslint:disable-next-line: no-http-string !(libname === "http://www.w3.org/2001/XMLSchema-datatypes" && (type === "QName" || type === "NOTATION"))) { throw new Error("datatype needs context but is not QName or NOTATION \ form the XML Schema library: don't know how to handle"); } if (datatype.needsContext) { // Change ns to the namespace we need. ns = fromQNameToURI(value, el); value = localName(value); el.setAttribute("ns", ns); el.replaceContent([new parser_1.Text(value)]); } const valuePattern = new patterns_1.Value(el.path, value, type, libname, ns, el.documentation); // Accessing the value will cause it to be validated. // tslint:disable-next-line:no-unused-expression valuePattern.value; break; } case "data": { // Except is necessarily last. const hasExcept = (el.children.length !== 0 && el.children[el.children.length - 1] .local === "except"); type = el.mustGetAttribute("type"); libname = el.mustGetAttribute("datatypeLibrary"); const lib = datatypes.registry.find(libname); if (lib === undefined) { throw new datatypes.ValueValidationError(el.path, [new datatypes.ValueError(`unknown datatype library: ${libname}`)]); } if (lib.types[type] === undefined) { throw new datatypes.ValueValidationError(el.path, [new datatypes.ValueError(`unknown datatype ${type} in \ ${(libname === "") ? "default library" : `library ${libname}`}`)]); } const params = el.children.slice(0, hasExcept ? el.children.length - 1 : undefined).map((child) => ({ name: child.mustGetAttribute("name"), value: child.text, })); const data = new patterns_1.Data(el.path, type, libname, params); // This causes the parameters to be checked. We do not need to do // anything with the value. // tslint:disable-next-line:no-unused-expression data.params; break; } default: } // tslint:disable-next-line: no-http-string if (libname === "http://www.w3.org/2001/XMLSchema-datatypes" && // tslint:disable-next-line:no-non-null-assertion warnAboutTheseTypes.includes(type)) { this.warnings.push(`WARNING: ${el.path} uses the ${type} type in library ${libname}`); } for (const child of el.children) { if ((0, parser_1.isElement)(child)) { this.walk(child); } } } } exports.DatatypeProcessor = DatatypeProcessor; //# sourceMappingURL=common.js.map