Arrangement of the patterns
So far only Schematron schemata containing a single rule have been introduced. When arranging several rules, the last unknown element of our Schematron schema is used: the <pattern> element.
Frequent errors in the arrangement of patterns
In most cases, a special arrangement is not required and each rule can be nested into an own <pattern> element. Which means that the <pattern> elements are strung together. The patterns and the rules contained therein are equal, and similar to the tests, there is no functional distinction of the rules because of the arrangement in the schema.
In contrast, several rules in one <pattern> element can increase the performance of the schema. A carefully considered arrangement of the patterns can be used for functional purposes in the case it is handled with experience and a suitable error query is used. Firstly, let us deal with the possible error source:
<pattern>
<rule context="ark:animal[@carnivore='yes']">
<report test="parent::*/ark:animal[@carnivore='no']">
There are carnivores and herbivores in one accommodation.
The animals are not a food source!
</report>
<report test="parent::*/ark:animal/ark:weight < (ark:weight div 2)">
Noah, this carnivore is too strong (heavy) for its roommate.
The carnivore could use it as a food source.
</report>
</rule>
<rule context="ark:animal">
<report test="count(parent::*/ark:animal[ark:species=current()/ark:species]) < 2">
There are less than two animals of this species in this accommodation.
</report>
</rule>
</pattern>
Basically, there is nothing wrong with this pattern. A pattern can absolutely consist of several rules. However, regarding the analysis, it must be taken into account that within a pattern the order of the rules plays an important role.
The following principle applies:
For a pattern each node of the instance can only be selected once as context node of a rule. If the node applies to the context condition of several rules of a pattern, the node will only be selected as context node of the first suitable rule in the pattern.
This slightly complex principle can also be illustrated: Each rule of a pattern is a sieve. The sieves are put on top of each other in the same order as the rules in the pattern. Now, the nodes of the instance are poured like sand through this sieve cascade. If a node applies to a rule and is blocked by the sieve, it will not reach the lower sieve in the first place which would have possibly also sorted out the node.
What does it mean to the above-mentioned pattern?
For a start, each rule is viewed separately: We already know the first rule. It selects all carnivores and checks whether the respective parent element (<room>) contains an animal which is not a carnivore and whether the animal could be a danger for another animal.
The second rule selects all animals. The test ensures that the parent element must not contain more than two animals of this kind (including the selected animal).
However, if the above principle of the order is included within patterns, the second rule will no longer check each animal. Since animals being carnivores are selected by the first rule as context node, the second rule only checks the herbivores. However, that is not intended by the rule. If this rule shall check – as intended – for all animals whether there is more than one pair, it has to be swaped out into a separate pattern:
<pattern>
<rule context="ark:animal[@carnivore='yes']">
<report test="parent::*/ark:animal[@carnivore='no']">
There are carnivores and herbivores in one accommodation.
The animals are not a food source!
</report>
<report test="parent::*/ark:animal/ark:weight < (ark:weight div 2)">
Noah, this carnivore is too strong (heavy) for its roommate.
The carnivore could use it as a food source.
</report>
</rule>
</pattern>
<pattern>
<rule context="ark:animal">
<report test="count(parent::*/ark:animal[ark:species=current()/ark:species]) < 2">
There are less than two animals of this species in this accommodation.
</report>
</rule>
</pattern>
Copyright © dpunkt.verlag GmbH 2011
Printing of the online version is permitted exclusively for private use. Otherwise this chapter from the book "Schematron - Effiziente Business Rules für XML-Dokumente" is subject to the same provisions as those applicable for the hardcover edition: The work including all its components is protected by copyright. All rights reserved, including reproduction, translation, microfilming as well as storage and processing in electronic systems.
dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, fon 06221-14830, fax 06221-148399, hallo(at)dpunkt.de