Skip to main content

Schematron

Schematron is a rule-based validation language for XML documents. In Semantic Treehouse, Schematron files implement the business rules that go beyond structural (XSD) validation: conditional constraints, cross-field checks, and codelist assertions.

Maintainers upload or write Schematron files in the Configure validator screen, where they are associated with a syntax binding and used during validation.

Schematron rule sets in Semantic Treehouse​

Each rule set in the Configure validator screen needs:

  • a Name, which is shown to users in the validator; and
  • either an uploaded file or inline content, never both and never neither. If this isn't the case, saving shows an error below the content editor.

Rule sets that had no name were given a generated name starting with "Ruleset - ". Rename them so users can recognize them in the validator.

Schematron structure​

See: http://www.datypic.com/sc/schematron/ss.html

Schema element <sch:schema>​

The top-level element of a Schematron schema.

A schema consists of <sch:phase>, <sch:pattern>, <sch:let> and other elements. The important elements are explained below.

Phase element <sch:phase>​

A grouping of patterns, to name and declare variations in schemas, for example, to support progressive validation.

Pattern element <sch:pattern>​

A set of rules giving constraints that are in some way related.

Let element <sch:let>​

A declaration of a named variable.

Common pitfalls and mistakes​

Rule context must be unique within a pattern​

See: http://schematron.com/2018/07/the-most-common-programming-error-with-schematron/

A node (xml elements) will only match one rule per pattern: the first one that matches.

So e.g. if you have the following rules:

<pattern>
<rule id="r1" context="a"></rule>
<rule id="r2" context="b"></rule>
<rule id="r3" context="a | b"></rule>
<rule id="r4" context="*"></rule>
</pattern>

When you validate a document with element <a>, it will only fire rule r1. Element <b> will only fire rule r2 and any other element will fire rule r4.

If you do want element <a> to fire rule r1, r3 and r4 you must place those rules in separate patterns, like so:

<pattern>
<rule id="r1" context="a"></rule>
<rule id="r2" context="b"></rule>
</pattern>
<pattern>
<rule id="r3" context="a | b"></rule>
</pattern>
<pattern>
<rule id="r4" context="*"></rule>
</pattern>

Choose the context correctly​

Selecting attributes is not possible. The context must result in zero/one/more element nodes

E.g. this is NOT possible:

<rule context="//@currencyID" >
<assert test=". = 'EUR'">The attribute currencyID must contain value 'EUR'.</assert>
</rule>

You should do this instead:

<rule context="//*[@currencyID]" >
<assert test="@currencyID = 'EUR'">The attribute currencyID must contain value 'EUR'.</assert>
</rule>

Never leave a context or test empty​

Every <sch:rule> needs a non-empty context, and every <sch:assert> and <sch:report> needs a non-empty test. One empty value makes the whole Schematron file invalid, so the validator cannot check any rule in it. The message text of an assertion may be empty, but users then get no explanation when it fails.

Give rules a recognizable identifier​

The validation result shows an identifier for each failed rule. For Schematron written in the inline content editor, add an fpi attribute with the identifier your users know; otherwise the rule's id is shown. For uploaded files, the id is shown, so choose a meaningful one:

<sch:rule id="NL-R-001" fpi="NL-R-001" context="...">

Testing Schematron files​

Before deploying a Schematron file in production, test it against sample XML documents using the Validator. Upload a message and verify that your rules fire correctly (expected errors appear) and don't produce false positives.

See also​

  • Business rules: managing business rules in natural language with Schematron implementations.
  • Configure validator: uploading and managing Schematron files for a syntax binding.
  • Validator: using the validator to test messages against your rules.