use std::sync::Arc;
use schematron::schema::{MemoryResolver, Resolver, SchemaOptions};
use schematron::{Document, Error, Schema};
const MAIN: &str = r#"
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
<title>Composed rules</title>
<include href="structure.sch"/>
<include href="lines.sch"/>
</schema>
"#;
const STRUCTURE: &str = r#"
<pattern xmlns="http://purl.oclc.org/dsdl/schematron" id="structure">
<rule context="order">
<assert test="@id">An order needs an id.</assert>
</rule>
</pattern>
"#;
const LINES: &str = r#"
<pattern xmlns="http://purl.oclc.org/dsdl/schematron" id="lines">
<rule context="line">
<assert test="@qty">Every line needs a qty.</assert>
</rule>
</pattern>
"#;
#[derive(Debug)]
struct NoIncludes;
impl Resolver for NoIncludes {
fn resolve(&self, href: &str, _base: Option<&str>) -> schematron::Result<String> {
Err(Error::Resolve {
href: href.to_string(),
message: "includes are disabled for this schema".to_string(),
})
}
}
fn main() -> schematron::Result<()> {
let resolver = MemoryResolver::new()
.with("structure.sch", STRUCTURE)
.with("lines.sch", LINES);
let options = SchemaOptions::new().with_resolver(Arc::new(resolver));
let schema = Schema::from_str_with(MAIN, &options)?;
println!("compiled {} pattern(s) from includes", schema.patterns().len());
let document = Document::from_str("<order><line/></order>")?;
let report = schema.validate(&document)?;
for failure in report.failures() {
println!(" {} — {}", failure.location, failure.text);
}
let locked = SchemaOptions::new().with_resolver(Arc::new(NoIncludes));
match Schema::from_str_with(MAIN, &locked) {
Ok(_) => println!("\nunexpected: includes were resolved"),
Err(error) => println!("\nwith includes disabled: {error}"),
}
Ok(())
}