ShEx
purrdf-shex (re-exported as purrdf::shex)
is PurRDF’s native
Shape Expressions Language 2.1 engine: the
schema layer and the shape-map validator, pure Rust and wasm-clean.
Schemas: ShExC and ShExJ
- ShExC (the compact syntax, spec §6) — a hand-rolled lexer and
recursive-descent parser covering the full grammar: directives,
start, theAND/OR/NOTshape algebra, node constraints and the facet table, value sets with stems/ranges/exclusions, triple expressions with all cardinality forms,$/&labels and inclusions,^inverse, annotations and%…{ … %}semantic actions, with relative-IRI resolution againstBASEviapurrdf-iri. - ShExJ (the JSON wire format, spec Appendix A) — strict, round-tripping serde support matching the shexTest ground truth.
- Structural checks (spec §5.7) — dangling references, label collisions, reference-only cycles, and the negation-stratification requirement.
use purrdf::shex::{check_structure, parse_shexc, to_shexj};
let schema = parse_shexc(
"PREFIX ex: <http://example.org/>\n\
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n\
ex:S { ex:p xsd:integer? }",
None,
)?;
check_structure(&schema).expect("well-formed");
let json = to_shexj(&schema);
Hard-fail discipline: every malformed schema is a typed ShexError — no
lenient mode, no panics on any input.
Validation with shape maps
Validation (spec §5.2–§5.5) is fixed shape-map validation over the frozen
purrdf-core dataset IR, in interned TermId space: you supply
(node, shape) associations and the validator decides conformance for each.
It covers node constraints (node kind, datatype with lexical-validity
checking, string/numeric facets, value sets with stems and exclusions),
EXTRA/CLOSED triple-expression matching with EachOf/OneOf
partitioning and group cardinalities, inverse constraints, typing-based
recursion, and an EXTERNAL resolver hook.
From Python:
from purrdf_native import shex
result = shex.validate(my_schema_shexc, my_data_ttl,
[("https://example.org/alice", "https://example.org/PersonShape")])
print(result["conforms"])
Conformance
The engine is gated against the vendored official
shexTest suite, pinned at tag
v2.1.0 (vectors/shexTest/): the full validation/ manifest, the
schemas/ ShExC/ShExJ pairs and round-trips, and the negative syntax and
negative structure suites. At the time of writing the validation manifest
passes 1,105/1,105 attempted cases with zero expected-failures and an
empty trait-skip list (imports and semantic actions included); the live
scoreboard is
docs/CONFORMANCE.md.
Reported conformance is logic-level (pass/fail parity), per suite convention; result-structure conformance is upstream-experimental.
SHACL or ShEx?
PurRDF implements both natively over the same IR, so the choice is yours, not the toolkit’s: SHACL suits constraint reporting (violations with severities, SARIF output) and SHACL-SPARQL escape hatches; ShEx suits schema-like conformance decisions over explicit shape maps.