Skip to content

Commit d4589aa

Browse files
committed
feat(lance-graph-ontology): PR-bO-15 SchematronHydrator + ZUGFeRD rules
Second Tier-C hydrator. Schematron (ISO/IEC 19757-3) is the rule- language layer that sits on top of XSD across every major e-business standard — EN 16931, PEPPOL, XRechnung, ZUGFeRD, UBL, ISO 20022 all ship structural XSD + behavioral .sch business rules. This hydrator generalizes the rule-extraction shape so each future spec only needs glue, not new hydrator code. New SchematronHydrator (minimal name-extraction shape): - crates/lance-graph-ontology/src/hydrators/schematron.rs - Walks `<assert id="..." test="..." flag="...">` and `<report id="...">` and `<pattern id="...">` elements via quick-xml streaming, interns each as `{base_iri}/{element}/{id}` - Additionally scans text bodies for bracketed business-rule IDs like [BR-52], [BR-CO-03], [BR-DE-1], [PEPPOL-EN16931-R008] — these are the canonical EN16931 / PEPPOL / DE / VAT-category rule identifiers used by cross-spec alignment. Each distinct ID interns as `{base_iri}/rule/{rule-id}`. - Strict business-rule ID validator (uppercase-only, dash-segmented, no leading digit / double dash / trailing dash) keeps the rule namespace clean of false positives from message text. - 3 unit tests verify the validator + end-to-end interning on a tiny in-memory .sch fixture. bO-15 ZUGFeRD rules (OGIT::ZUGFERDRULES_V1, slot 31): - hydrate_zugferd_rules() points the SchematronHydrator at the FACTUR-X_EN16931.sch file that already shipped with bO-16. - Base IRI urn:schematron:factur-x-1.08-en16931 — stable URN for downstream alignment to PEPPOL / EN16931 / FeRD rule registries. - inherits_from: Some(OGIT::ZUGFERD_V1.0) — rule namespace is meaningless without the structural CII namespace. - 5 smoke tests verify the EN16931 anchor rules (BR-52 / BR-45 / BR-CO-03 / BR-CO-17 / BR-S-08 / BR-Z-08 / BR-DEC-19), PEPPOL extension (PEPPOL-EN16931-R008), schema-level FX-SCH-A-* IDs that KoSIT validator output references directly, and rule-family coverage (BR-CO / BR-DEC / BR-S / BR-Z / PEPPOL). - ~510 IRIs hydrated: 301 distinct schema assert IDs (428 elements collapse to 301 — some IDs are reused across patterns) + ~209 distinct bracketed business-rule IDs. Inspection findings documented in tests + LICENSES/ZUGFERD.txt: - 191 <report> elements present but NONE have @id (Schematron-1 style; text bodies still contribute business-rule IRIs). - 0 patterns / 0 phases with @id. Side fix: factored out the XsdHydrator interning-closure type alias to clear a clippy type_complexity warning. Now 5 clippy warnings, all pre-existing oxrdf deprecations. All 106 lance-graph-ontology tests pass; downstream consumers build clean.
1 parent 9e65307 commit d4589aa

9 files changed

Lines changed: 646 additions & 8 deletions

File tree

LICENSES/ZUGFERD.txt

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ up the Factur-X 1.08 EN16931 profile:
4242
standard_UnqualifiedDataType_100.xsd (UDT)
4343

4444
Plus the Schematron business-rule file `FACTUR-X_EN16931.sch` and
45-
the code-list database `FACTUR-X_EN16931_codedb.xml`. Neither is
46-
hydrated by the current XsdHydrator — they are shipped for future
47-
SchematronHydrator (business-rule projection) and CodeListHydrator
48-
(currency/unit code interning) PRs.
45+
the code-list database `FACTUR-X_EN16931_codedb.xml`.
46+
47+
The `.sch` file is hydrated by SchematronHydrator (PR-bO-15) into
48+
the sibling slot OGIT::ZUGFERDRULES_V1 — see below. The codedb XML
49+
is shipped for a future CodeListHydrator PR (currency / unit / tax
50+
code interning), not hydrated today.
4951

5052
Hydration
5153
---------
@@ -67,3 +69,34 @@ Declares inherits_from: Some(OGIT::DOLCE_V1.0). Future alignment:
6769
These alignments are NOT baked into the XSDs (they're XML schema
6870
constraints, not OWL axioms); they're left to downstream consumers
6971
that need the cross-G projection.
72+
73+
ZUGFeRD business rules (PR-bO-15)
74+
---------------------------------
75+
Hydrated as OGIT::ZUGFERDRULES_V1 via SchematronHydrator. Source:
76+
data/ontologies/zugferd/FACTUR-X_EN16931.sch (Apache-2.0, shipped
77+
in this repo alongside the XSDs).
78+
79+
The hydrator interns every Schematron `<assert id="...">` ID and
80+
every bracketed business-rule identifier `[BR-NN]` / `[BR-CO-NN]` /
81+
`[BR-DEC-NN]` / `[BR-{S,Z,E,AE,G,IC,K,L,M,O}-NN]` / `[PEPPOL-EN16931-*]`
82+
found in message bodies. All IRIs live under the URN base
83+
`urn:schematron:factur-x-1.08-en16931/{assert,report,pattern,rule}/{id}`.
84+
85+
Inspection of the EN16931 profile finds:
86+
87+
- 301 distinct `<assert>` @id values (some IDs are reused across
88+
patterns, so 428 assert elements collapse to 301 IRIs).
89+
- 191 `<report>` elements, none with @id (Schematron-1 style;
90+
their message bodies still contribute business-rule IRIs).
91+
- 0 patterns and 0 phases with @id.
92+
- ~209 distinct bracketed business-rule IDs spread across the
93+
EN16931 / PEPPOL / DE / VAT-category extension families.
94+
95+
Total: ~510 IRIs in OGIT::ZUGFERDRULES_V1.
96+
97+
Deferred follow-up:
98+
- XPath `<rule context="..."/>` resolution into edges back to XSD
99+
types (would link `urn:schematron:.../rule/BR-52` ⊑ `ram:ApplicableTradeTax`).
100+
- Severity (`@flag="warning|error|fatal"`) projection.
101+
- Phase / pattern / rule structural edges.
102+
- `<let>` variable resolution.

crates/lance-graph-contract/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ const CANONICAL_SLOTS: &[(&str, u32)] = &[
4141
// German hybrid PDF/A-3+XML invoice format aligned with EN 16931.
4242
// Hydrated as IRI-interning over UN/CEFACT CII XSDs via XsdHydrator.
4343
("ZUGFERD", 30),
44+
// L3 e-invoicing business rules (PR-bO-15). Schematron assertion /
45+
// report IDs from the ZUGFeRD validator config, plus the bracketed
46+
// EN16931 / PEPPOL / CO / DE business-rule IDs from the message
47+
// bodies. Hydrated via SchematronHydrator.
48+
("ZUGFERDRULES", 31),
4449
];
4550

4651
fn canonical_slot(token: &str) -> Option<u32> {

crates/lance-graph-ontology/src/hydrators/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub mod owltime;
2525
pub mod provo;
2626
pub mod qudt;
2727
pub mod schemaorg;
28+
pub mod schematron;
2829
pub mod skos;
2930
pub mod xsd;
3031
pub mod zugferd;
@@ -36,6 +37,9 @@ pub use owltime::{hydrate_owltime, hydrate_owltime_from};
3637
pub use provo::{hydrate_provo, hydrate_provo_from};
3738
pub use qudt::{hydrate_qudt, hydrate_qudt_from};
3839
pub use schemaorg::{hydrate_schemaorg, hydrate_schemaorg_from};
40+
pub use schematron::SchematronHydrator;
3941
pub use skos::{hydrate_skos, hydrate_skos_from};
4042
pub use xsd::{collect_xsd_files, XsdHydrator};
41-
pub use zugferd::{hydrate_zugferd, hydrate_zugferd_from};
43+
pub use zugferd::{
44+
hydrate_zugferd, hydrate_zugferd_from, hydrate_zugferd_rules, hydrate_zugferd_rules_from,
45+
};

0 commit comments

Comments
 (0)