XQuery implementation of Schematron
Tested under BaseX 10.x.
- Install BaseX version 10 or later.
- Download the latest release and navigate to the root directory of the extracted archive (containing
*.xqm
and*.bxs
files).
XQS provides two methods of validating with a Schematron schema, by either:
- evaluating the schema dynamically; or
- compiling the schema to an XQuery main module.
Basic command scripts are provided to run XQS using BaseX in standalone mode. This allows you to use XQS as a straightforward, standalone validator.
The -b
options given below simply bind a variable; their order is not significant.
The named example files used in the commands below are also included in this repository, alongside the command scripts.
Run evaluate.bxs
, passing the locations of the XML document (uri
) and the Schematron schema (schema
):
basex -buri=myDoc.xml -bschema=mySchema.sch evaluate.bxs
You can also pass an optional phase (as phase
):
basex -buri=myDoc.xml -bschema=mySchema.sch -bphase=myPhase evaluate.bxs
The output is in the Schematron Validation Reporting Language (SVRL) format.
Run compile.bxs
, passing the location of the Schematron schema (schema
):
basex -bschema=mySchema.sch compile.bxs
Example output for this command is shown in mySchema.xqy
.
If your schema uses phases, you can also select a phase:
basex -bschema=mySchema.sch -bphase=myPhase compile.bxs
Example output for this command is shown in mySchema-myPhase.xqy
.
The output from compile.bxs
is an XQuery main module, which contains two external variables allowing the document to validate to be passed in:
$Q{http://www.andrewsales.com/ns/xqs}uri
$Q{http://www.andrewsales.com/ns/xqs}doc
$uri
should be a URI. If your XQuery processor supports it, you can use $doc
to pass a document node instead.
CAUTION When compiling, avoid using the XQS namespace (http://www.andrewsales.com/ns/xqs
) in your schema, which XQS uses for variables internal to the application.
For convenience, if you have compiled a schema using compile.bxs
, you can run validate.bxs
, passing the schema and document locations:
basex -bschema=mySchema.xqy -buri=myDoc.xml validate.bxs
The output is again SVRL.
You can also use the XQuery API contained in xqs.xqm
, e.g.
import module namespace xqs = 'http://www.andrewsales.com/ns/xqs' at 'path/to/xqs.xqm;
xqs:validate(doc('myDoc.xml'), doc('mySchema.xml)/*)
or
xqs:compile(doc('mySchema.xml)/*)
If you use phases, you can pass them in like so:
xqs:compile(doc('mySchema.xml)/*, 'myPhase')
or
xqs:validate(doc('myDoc.xml'), doc('mySchema.xml)/*, 'myPhase')
Inclusions are resolved and abstract rules and patterns instantiated automatically, whether you are compiling or evaluating a schema. There is no need to carry out a separate initial process.
If you do wish to perform this step only, in order to produce a fully resolved and instantiated schema, include-expand.bxs
is provided for this purpose. Run it, passing the location of the schema, as follows:
basex -bschema=myModularSchema.sch include-expand.bxs
Example output for this command is shown in myResolvedSchema.sch
.
The output from include-expand.bxs
is the schema with inclusions resolved and abstract patterns and rules instantiated. (Note that this command script can be used on any valid Schematron schema, regardless of the target query language; it does not depend on the query language binding the schema declares.)
The test suite is found in the test/
sub-directory.
To run all the tests there, at the command line, specify the -t
option and the path to the test
directory:
basex -t path/to/test
The command returns 0
if all tests pass, otherwise 1
.
This is an early release and should be treated as such. Bug reports, feature requests and other observations are welcome. Please refer to the issues for a list of known bugs and planned enhancements.
Your schema should specify a queryBinding
value of : xquery
, xquery3
or xquery31
, in any combination of upper or lower case.
When using an XSLT implementation, a rule's context
attribute with an XPath such as foo
will match any instance of that element in the document being validated, and the rule is said to "fire".
The key difference with XQS is that it evaluates these XPaths in the context of the document root, so the expression foo
will only match if it is the root element.
To address this, XPaths should be changed as appropriate, e.g. to //foo
, which will ensure that the element would be matched anywhere in the document.
If your schema was intended for use with an XSLT implementation, then any user-defined functions will most likely be expressed using xsl:function
.
XQS is a pure XQuery implementation and doesn't recognize these, so they need to be re-written as XQuery, contained in function
elements in the XQuery namespace, e.g.
<function xmlns='http://www.w3.org/2012/xquery'>
declare function local:foo($i as xs:int) as xs:int{
$i * $i
};
</function>