Schematron validation with BizTalk

At one of our customers, we had to implement an extensive amount of content validation checks.
We looked at different ways to do this; custom code, BRE, mapping, Schematron, etc. In this blog post we will give an overview on how we achieved to validate business rules by using the Schematron ISO standard.

So, what is Schematron?

Explanation from Wikipedia ( )

In markup languagesSchematron is a rule-based validation language for making assertions about the presence or absence of patterns in XML trees. It is a structural schema language expressed in XML using a small number of elements and XPath.

In a typical implementation, the Schematron schema XML is processed into normal XSLT code for deployment anywhere that XSLT can be used.

Schematron is capable of expressing constraints in ways that other XML schema languages like XML Schema and DTD cannot. For example, it can require that the content of an element be controlled by one of its siblings. Or it can request or require that the root element, regardless of what element that is, must have specific attributes. Schematron can also specify required relationships between multiple XML files.

Constraints and content rules may be associated with “plain-English” validation error messages, allowing translation of numeric Schematron error codes into meaningful user error messages.

The latest version, 1.6, is based on XPath 2.0. In our project we used version 1.5 since we all know, .Net and XPath 2.0 don’t go hand in hand. There are workarounds, like using a framework such as Saxon. Unfortunately, it has a negative impact on performance. In our case up to 20 times slower.

Using, or more accurate, following the standard is simple; stick to the guidelines, create the xslt, and execute it against the xml messages. Any rule validation that fails will be returned. It’s that simple.

Let’s have a look at how it works by using the following example message:

Let’s say the message needs to meet the following rules:

  • Surname and Lastname can’t be empty
  • Value of Title needs to start with a capital letter.
  • If Company equals Integration.Team, CompanyAddress needs to be Veldkant 33A 2550 Kontich

When implementing the rules according to the Schematron standard, it will result in the following file:

As all xmls it need to start with the root element, schema. This includes the namespace, with prefix, of the xml or xmls that needs to be validated. The pattern record is a collection of rules with the test, assert, that are evaluated.

The value of the name attribute on pattern, is included in the generated xml file. I’ll come back on that further on. The record rule contains the attribute context, it states the context for the assert to be validated. So, if Surname is present it needs to be have a value. If not, the message between the assert record will be used as the error description. Pay attention that this is the opposite of an if-test.

The XPath expression used in context needs to point to a node in the xml, the one in test can be any XPath 1.x compliant expression, as long as it returns true of false. It’s also convenient that all the rules are evaluated, so you know all the issues at once.

The next step is to generate the xslt file from the schematron schema. This can be done by executing the xslt script skeleton1-5.xslt which will generate an xslt file that can be used inside BizTalk Server.

When investigating the generated xslt, you’ll see that a context is translate into a template. The test is transformed into a choose, where when corresponds to the happy path. And otherwise will handle the unhappy path.

When looking at the output file, you’ll notice all the patterns and the rules that were fired. Or in order words, the rules where the context evaluated against an existing node.

Looking at active-pattern, the first thing that pops up is the name. It corresponds to the name attribute on the pattern record in the Schematron file.
fired-rule comes in handy to see with rules were executed. Or in other words, for which rules the context evaluated against an existing node.
One very practical ‘feature’ is that the location is provided when a rule fails. It corresponds to the location of the node defined in the context attribute of the rule.

Above steps are the reals basics in order to perform schematron based validation. There is a lot more to the standard, so I suggest you have a look at it.

Where you’ll use the generated xslt, is completely up to you. It’s possible to use it almost anywhere in BizTalk; pipeline component, orchestration, even BizTalk maps.


  • Take the time to learn XPath notations, you’ll be amassed by the possibilities
  • Keep in mind that the context refers to a node or node set
  • Make something to quickly generate and test the xslt files, it will save a lot of time
  • Keep in mind that you’re limited to XPath/xslt 1.x when using it within BizTalk.


The Schematron standard has more features then the ones used in this blog. Although we didn’t need them, I think it’s worth diving into them, maybe they can be of use in future projects.

We don’t think it’s an opponent for the BRE, more like another way/manner to achieve the same goal. We do find it easier to do more complex node selections.


1 Schematron 1.5