XQuery/Validation with Schematron

Motivation
You want to check your XML document against a set of business rules. These rules may be more complex then a single pass XML Schema can perform.

Overview
Schematron provides a different approach to validation than a standard Schema. Rather than stating the correct form of a document, Schematron allows you to define rules which can be applied as needed. You can also specify rules in one part of a document that reference other parts of the document using XPath expressions. This is very useful when a document is created in stages and specific business rules need to be checked prior to using the data.

Schematron may also work along side of traditional XML Schemas. You can use XML Schemas to check the overall document structure and data types and use Schematron to express rules that can be done best with XPath rules.

Schematron is also ideal because it allows the rule designer to specify the exact error messages for rules. XML Schema error messages are often not easy for users to understand.

Example
Here's an example: prior to sending a confirmation email for a "school-booking", the booking must contain a school/id, a Teacher's email-address, and a Date for the booking. The Date must be in the future.

To apply this schema from an XQuery:

And the results (edited for clarity):

The results can be used to highlight the error and display a message to the user.

Setup in eXist-db
I've chosen the XSLT 2.0 version of the Schematron validation - so eXist-db needs to have Saxon 9 installed. (...)


 * 1) Get the iso-schematron-xslt2 and upload the (unzipped) contents to your database.
 * 2) Create a schema in the db
 * 3) Compile and run the schema on your data

XQuery Module for ISO Schematron
Jing only supports Schematron 1.5. A more advanced version of Schematron is the ISO Schematron, which Jing will not run. To get this to work you must "compile" your Schematron rules using XSLT.

The following is a sample XQuery module that does this compilation.

Note that the xslt assumes an include file.