Conformance
A summary. spec/conformance/ is authoritative, and states the limits and deliberate divergences in full.
ISO/IEC 19757-3
What is implemented
| Area | Status | Note |
|---|---|---|
| schema, pattern, rule, assert, report | Full | |
| ns, let, phase, active, include, extends | Full | |
| Abstract patterns (abstract, is-a, param) | Full | |
| Abstract rules (rule/@abstract + extends) | Full | |
| diagnostics, properties, value-of, name, emph, span, dir | Full | |
| @flag, @role, @subject, @see, @icon, @fpi | Full | |
| pattern/@documents | Full | |
| key and key() | Full | A non-ISO extension — see spec/keys/. |
| Streaming validation (--stream) | Full | A non-ISO extension, for schemas provably local to one record — see spec/streaming/. |
| Phases, #ALL, #DEFAULT, @defaultPhase | Full | |
| SVRL output | Full | |
| XPath 1.0 — 13 axes, 27 core functions, exact conversion semantics | Full | |
| XPath document(), with cross-document node-sets | Full | |
| document(uri, base) | Full | Resolves against the second argument's first node. |
| XPath 2.0 kind tests as node tests — element(), attribute(id), document-node() | Full | Under an xslt2 binding. |
| XPath 2.0 sequences, dates, durations, type operators, value and node comparisons, for, some, every, ranges, regular expressions | Subset | See spec/xpath2/. |
| XPath 3.0 function items, =>, ||, !, let, Q{uri}local, the higher-order sequence functions | Subset | See spec/xpath3/. |
| queryBinding="xslt", "xpath", or absent | Full | |
| queryBinding="xslt2", "xpath2" | Subset | See spec/xpath2/. |
| queryBinding="xslt3", "xpath3" | Subset | See spec/xpath3/. |
| queryBinding="xslt31" and later | Refused | By default. |
| extends rule and extends href, with #fragment identifiers | Full |
XPath 2.0
A subset, with a hard edge
XPath 2.0 is a different language, not XPath 1.0 with extra functions. The crate implements a documented subset of it — regular expressions, conditionals, and the string and numeric functions schemas actually use — and makes everything outside that subset a hard error naming the construct, never a wrong answer.
An xslt2 schema may still evaluate some things with XPath 1.0 semantics.
spec/xpath2/ is explicit about what is
in, what is out, and the handful of places where that happens. Read it
before depending on an xslt2 binding.
XPath 3.0
Function items and the operators built on them
An xslt3/xpath3 schema gets everything XPath 1.0
and 2.0 already provide, plus XPath 3.0's own additions: inline function
expressions, named function references, and dynamic calls — the machinery
a real for-each() needed — the arrow operator =>, string concatenation ||, the simple map
operator !, the let expression, EQNames
(Q{uri}local, naming an element or attribute by
namespace URI directly — node name tests only, not variable or function
names), and the rest of the higher-order sequence function library
(filter, fold-left, fold-right, for-each-pair, function-lookup, function-arity, function-name). As with
XPath 2.0, everything outside the documented subset is a hard error
naming the construct.
Maps, arrays, and sort are XPath 3.1, not 3.0 — and stay refused.
spec/xpath3/ states exactly what
is implemented, and why neither fn:sort nor union types in
casts and signatures were ever actually XPath 3.0 gaps to begin with —
the first does not exist until 3.1, and the second has no literal
syntax in any version's grammar at all.
Measured
Against the reference implementation
Beyond the test suite, the crate is compared against the ISO Schematron reference implementation — the XSLT stylesheets that compile a schema into a validator — over the whole corpus. Twenty of twenty-three cases agree exactly; the other three are documented, and in each the difference is the reference's rather than this crate's.
sh tests/differential/fetch-skeleton.sh /tmp/skeleton
SCHEMATRON_SKELETON=/tmp/skeleton cargo test --test differential -- --ignoredThe documented divergences include:
- rules on
text(),comment()and processing instructions, which the reference never fires; - a
letthat shadows an outer one, which the reference refuses outright; - a rule's
@flag, which the reference drops.
Two checks
Lint asks one question; portability asks another
--lint reports constructs that are legal but almost certainly
wrong — a shadowed rule, an unprefixed name in a namespaced schema, a
variable or key nothing uses, a rule that reports nothing.
schematron --schema rules.sch --lint--portability asks whether the schema will behave the same
under another Schematron processor. What it reports is not
wrong — it is correct, and works here, and the reference
implementation treats it differently. Each of the seven checks is backed by
a divergence in spec/conformance/, established by running
both implementations against the same schema.
schematron --schema rules.sch --portabilityThey are separate on purpose, because a linter that reports correct code gets switched off.
The authoritative conformance document What is next, and what is not planned The whole specification