A luminary from the W3C XML Schema Working Group once ejaculated during a meeting in around year 2000:

But you cannot do anything without types!

At the time, the statement puzzled me: SGML had mudded along fine without a type system at all (or, at least, one that is focussed entirely on SGML’s needs, not on integration with other systems.) But it is a legitimate POV to allow, even if we don’t drink all the Kool-Aid.

This attitude explains the central principle of XSD (XML Schemas): you are trying to attach type information to elements, simple data content and attribute values. That type information is, ideally, friendly to data binding systems, to allow efficient representation and access of data in optimal, native non-XML forms : mappings to RDBMS or whatever.

The result of XSD validation is a “Post Schema Validation Infoset”. (Actually, this is a post-XML infoset too: it does not have any canonical XML or text representation, which is a strategic blunder. The rise of JSON was, perhaps, nature abhorring that vacuum.) Contrast with RELAX NG which has no allocation of types to nodes, as a standard output of the system. Or with Schematron, which has a standard output in an XML language, SVRL.

So my question today is this: does Schematron define types? Is it a type system? To avoid quibbles about named types and anonymous types, we could just consider Schematron abstract rules, which let you bundle a whole heap of assert, report and let elements a named collection for use in multiple situations. Is an abstract rule a type?

I would say that, in the sense that the XSD experts use “type”, Schematron is not, out-of-the-box, a type system in the way that XSD is. In XSD, you want to be able to say of your document graph “This node is this type”. But is that what we are doing in Schematron, for example in this case:

<sch:rule abstract="true" name="table-less">
<sch:assert test="not(//table)">There should be no table</sch:assert>
</sch:rule>
<sch:rule context="meta[@category='agricultural']">
<sch:extends rule="table-less"/>
</sch:rule>

In that code we define and name some assertion. And then when we find some other element, we require that assertion.

But note that the assertion has nothing to do with the value of the meta element. It is not in any sensible way restricting or extending or constraining any of the values of that meta element. Consequently, I don’t think we can view Schematron as a type system in the way that XSD expects.

But I think we need to think bigger about what a type system is: in the example above what we are constraining is the whole document. So perhaps we can say that Schematron is in fact a type system, but it is a type system where the types (patterns and rules) attaches to the whole document. This is particularly so when considering patterns, which may contain multiple rules. XSD removed the idea of document types in favour of namespace-based node typing, and Schematron brings it back with a bang.

Finally, I should mention that actually Schematron has long had a mechanism to specify a particular node that should be taken as the “subject” of the rule. This is the rule/@subject attribute: I think it does, in fact, allow an XSD-equivalent way to map constraints to specific node. But I have never seen it used.
The new property mechanism in ISO Schematron 2016 allows annotations on rules too, which improves the support of type (or type-lookalike) reporting.