Schematron tests, lets, and message expressions can now use key() backed
by xsl:key declarations parsed from the schema, document() loading an
external file through an injected documentLoader, and current() resolving
to the rule context node. A node-keyed function-table factory threads
through the evaluation. Completes the Schematron audit.
A <pattern abstract="true"> is a template whose rule queries carry $name
references; a <pattern is-a="…"> with <param> children instantiates it,
substituting each parameter into the template's context, test, <let>
value, and <value-of select=> before the XPath is compiled. The
substitution is a single left-to-right pass, so a substituted value is
never rescanned and a short name never captures a longer one; $name
references that are not parameters stay as written. The template itself
contributes no rules.
<let> may now appear at schema and pattern level, not just in a rule.
Schema lets are evaluated once at the document root; pattern lets extend
them (also at the root); rule lets extend those at each context node. A
narrower-scope binding overrides a wider one of the same name.
Part of #80
An assert/report may reference <diagnostic> messages by id through its
diagnostics= attribute; each referenced diagnostic is rendered (with the
same value-of/name/let substitution) and appended to the finding for
extra per-failure detail. <diagnostics> is collected schema-wide.
Schema/pattern-level let, abstract patterns, and key()/document() remain.
Part of #80
A <rule abstract="true" id="x"> is a template that does not fire on its
own; a concrete rule pulls in its let bindings and assertions with
<extends rule="x"/>, prepended so the concrete rule extends rather than
replaces them.
Part of #80
<rule> may now declare <let name= value=> bindings, evaluated at each
context node in order (so a later binding can reference an earlier one
through $name). The bindings are available to the rule's assert/report
tests and to <value-of select="$name"> in messages, using the XPath
engine's existing variable support.
Schema- and pattern-level let, abstract rules/extends, diagnostics, and
key()/document() remain.
Part of #80
Two ISO Schematron gaps, the most validator-relevant first:
- Dynamic messages: an assert/report message is now a template, so
<value-of select=> renders the string value of its XPath at the context
node and <name> renders the node's name. A finding can report actual
values ("Age 120 must be under 100") instead of static text.
- Phases: <phase id><active pattern=> scopes which patterns run.
validate(_:phase:) honors a requested phase or the schema's
defaultPhase; nil or #ALL runs every pattern.
let variables, abstract rules/extends, diagnostics, and key()/document()
remain (the last depends on XSLT-style function injection).
Part of #80
Add PureXML.Validation.Schematron: compile a Schematron schema (matching
schema/pattern/rule/assert/report by local name, so the ISO and legacy
namespaces both work) and validate a document. A rule's context XPath
selects the nodes it fires on; each assert/report test is evaluated relative
to the node via the XPath context-node API. A failed assert is an error, a
matched report a warning; within a pattern a node fires the first matching
rule. Adds XPath.Query.nodes(over:) returning matched tree nodes so one tree
can be queried repeatedly.
Closes#52Closes#53Closes#25