{"id":16149,"library":"node-schematron","title":"node-schematron","description":"The `node-schematron` package provides a pure JavaScript implementation of the Schematron validation language, designed for use in Node.js environments, web browsers (with bundlers like Webpack), and as a command-line interface (CLI) tool. As of version 2.1.0, it offers a robust solution for validating XML documents against Schematron schemas, returning results as a JSON object. Key differentiators include its complete JavaScript implementation, avoiding native dependencies, and support for Schematron includes and various CLI options for file globbing and output reporters. The library utilizes `fontoxpath` for XPath 3.1 queries, though it notes that `fontoxpath` is not yet feature-complete. While there's no explicit release cadence, the project appears actively maintained, offering a flexible and integrated Schematron solution for JavaScript ecosystems.","status":"active","version":"2.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/wvbe/node-schematron","tags":["javascript","schematron","xml","validation","terminal","typescript"],"install":[{"cmd":"npm install node-schematron","lang":"bash","label":"npm"},{"cmd":"yarn add node-schematron","lang":"bash","label":"yarn"},{"cmd":"pnpm add node-schematron","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ESM is preferred in modern Node.js and browser projects, but CommonJS `require` is also supported for older Node.js environments as shown in the README example. TypeScript types are included.","wrong":"const { Schema } = require('node-schematron');","symbol":"Schema","correct":"import { Schema } from 'node-schematron';"},{"note":"Used to extend XPath capabilities with custom JavaScript functions. This utility is an alias for the same function in `fontoxpath`.","wrong":"const { registerCustomXPathFunction } = require('node-schematron');","symbol":"registerCustomXPathFunction","correct":"import { registerCustomXPathFunction } from 'node-schematron';"},{"note":"This is a method on an *instance* of `Schema`, not a static method on the `Schema` class itself. Always instantiate `Schema` first.","wrong":"Schema.validateString('<xml/>', options);","symbol":"validateString","correct":"schema.validateString('<xml/>', options);"}],"quickstart":{"code":"import { Schema } from 'node-schematron';\n\nconst schematronSchema = `\n<schema xmlns=\"http://purl.oclc.org/dsdl/schematron\">\n\t<pattern>\n\t\t<rule context=\"thunder\">\n\t\t\t<let name=\"lightning\" select=\"@foo\"/>\n\t\t\t<report test=\"$lightning = 'bar'\">\n\t\t\t\tSkeet boop <value-of select=\"$lightning\" />\n\t\t\t</report>\n\t\t\t<assert test=\"@type = 'storm'\">\n\t\t\t\tThunder must have a 'type' attribute with value 'storm'.\n\t\t\t</report>\n\t\t</rule>\n\t\t<rule context=\"xml\">\n\t\t\t<assert test=\"count(thunder) > 0\">\n\t\t\t\tXML document must contain at least one thunder element.\n\t\t\t</assert>\n\t\t</rule>\n\t</pattern>\n</schema>`;\n\nconst schema = Schema.fromString(schematronSchema);\n\nconst xmlToValidate = `\n<xml foo=\"err\">\n\t<thunder foo=\"bar\" type=\"storm\" />\n</xml>`;\n\nconst results = schema.validateString(xmlToValidate, { debug: true });\n\nconsole.log(JSON.stringify(results, null, 2));\n/* Expected Output for the report (assertion passes):\n[\n  {\n    \"isReport\": true,\n    \"context\": \"<thunder foo=\"bar\" type=\"storm\"/>\",\n    \"message\": \"\\n\\t\\t\\t\\tSkeet boop bar\\n\\t\\t\\t\"\n  }\n]\n*/","lang":"typescript","description":"This quickstart demonstrates how to initialize a Schematron `Schema` from a string and validate an XML string, logging the results."},"warnings":[{"fix":"Consult the `fontoxpath` documentation or `node-schematron` unit tests for specific supported XPath features. Consider implementing custom XPath functions using `registerCustomXPathFunction` for unsupported scenarios.","message":"The underlying XPath 3.1 implementation, `fontoxpath`, is noted as not yet feature-complete. Users relying on advanced or less common XPath 3.1 functions might encounter unsupported features or unexpected behavior.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Structure your Schematron patterns carefully, ordering rules from most specific to least specific. Use multiple patterns or refactor rules if multiple independent checks are required for the same node.","message":"Schematron's rule matching behavior can be counter-intuitive: within a single pattern, a node will only match the *first* rule whose context matches it. Subsequent rules in the same pattern for that node will not be evaluated, even if their contexts also match.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Avoid using `<xsl:function>` elements in your Schematron schemas. If custom logic is required, define JavaScript-based custom XPath functions using `registerCustomXPathFunction`.","message":"The library explicitly states that XSLT functions (`<xsl:function>`) are not supported. While there was a feature branch, it remains unimplemented.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Be aware of these unsupported attributes when authoring Schematron schemas, as they will be ignored by `node-schematron`. Adjust schemas to use supported constructs or external reporting mechanisms if these features are critical.","message":"Some ISO/IEC 19757-3 2016 (Schematron) attributes are not supported, including `@abstract`, `@diagnostics`, `@icon`, `@see`, `@fpi`, `@flag`, `@role`, and `@subject` in certain contexts.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For programmatic use, always provide an absolute or correctly resolved path to `resourceDir`. For CLI use, double-check `schematronLocation` and `globPattern` arguments, using absolute paths for clarity where possible. Use `--files` for explicit file lists if globbing is problematic.","message":"When using `resourceDir` for schema includes, ensure the path is correct and accessible. Incorrect paths will lead to `file not found` errors, and the CLI tool may default to `*.xml` if `globPattern` is not used correctly or `schematronLocation` is relative and ambiguous.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure the `resourceDir` option in `Schema.fromString()` or `Schema.fromFileSync()` points to the correct directory containing the included Schematron files. For CLI, verify `schematronLocation` and any paths referenced within the schema.","cause":"A Schematron schema uses `<include href=\"file.xml\" />` but the `resourceDir` option was not provided or points to an incorrect location, preventing the included file from being found.","error":"ENOENT: no such file or directory, stat '/path/to/include/files/file.xml'"},{"fix":"Refine the XPath expression to ensure it selects a single node or atomic value, or explicitly handle sequences using XPath functions like `string-join()`, `count()`, `head()`, `tail()`, or predicates like `[1]` to select a specific item from the sequence.","cause":"An XPath expression in an `assert` or `report` test, or a `value-of` select, evaluates to a sequence of multiple items where a single item is expected (e.g., trying to compare `//element` with a string, when `//element` matches multiple elements).","error":"Error: XPath error: \"Cannot convert XdmValue to single value: multiple values encountered\""},{"fix":"Carefully review the XPath expression for syntax errors. Validate the XPath against an XPath 3.1 validator. Pay attention to common pitfalls like incorrect axis specifiers, mismatched parentheses, or improper use of operators.","cause":"A syntax error in an XPath expression within a Schematron rule, often due to a typo or incorrect XPath syntax for the XPath 3.1 query language.","error":"Error: (XPath error) Cannot parse XQuery/XPath expression: Unexpected token \"|\" at position X"}],"ecosystem":"npm"}