Lösung der Schematron-Übungsaufgabe

<schema xmlns="http://purl.oclc.org/dsdl/schematron">
  <ns uri="http://www.schematron.info/arche" prefix="arc"/>
  <Pattern>                                                                       (1)
    <rule context="arc:tier[@geschlecht='männlich']">                             (1a)
      <report test="number(arc:alter) &gt; number(//arc:maxReproduktionsalter/arc:tier_art[arc:name=current()/arc:art]/arc:männlich)"> (1b)
      Das Männchen ist zu alt, Noah! Es wird sich nicht mehr fortpflanzen
      können. Sorge für die natürliche Auslese.</report>
    </rule>
    <rule context="arc:tier[@geschlecht='weiblich']">                             (1a)
      <report test="number(arc:alter) &gt; number(//arc:maxReproduktionsalter/arc:tier_art[arc:name=current()/arc:art]/arc:weiblich)"> (1b)
      Das Weibchen ist zu alt, Noah! Es wird sich nicht mehr fortpflanzen
      können. Sorge für die natürliche Auslese.</report>
    </rule>
  </pattern>
 
  <pattern>
    <rule context="arc:nutzlast">                                                 (2)
      <report test=". &lt; sum(//arc:gewicht)">                                   (2a)
      Noah, du hast zu viele Tiere an Bord. Die Ladung überschreitet die
      Nutzlast deiner Arche.</report>
    </rule>
  </pattern>

  <pattern>                                                                       (3)
    <rule context="arc:tier[@fleischfresser='ja']">
      <report test="parent::*/arc:tier[@fleischfresser='nein']">
      Es gibt Fleischfresser und Pflanzenfresser in einer Unterkunft. Die
      Tiere sind keine Nahrungsquelle!</report>
      <report test="parent::*/arc:tier/arc:gewicht &lt; (arc:gewicht div 2)">
      Noah, dieser Fleischfresser ist zu stark (schwer) für seinen Zimmergenossen.
      Er könnte ihn als Nahrungsquelle benutzen.</report>
    </rule>
    <rule context="arc:tier">
      <report test="parent::*/arc:tier/arc:gewicht &lt; (arc:gewicht div 10)">
      Noah, das Tier ist zu schwer für seine Zimmergenossen! Es könnte einen
      zertrampeln.</report>
    </rule>
  </pattern>
 
  <pattern>
    <rule context="arc:tier">                                                     (4)
      <report test="count(//arc:tier[arc:art=current()/arc:art]) &gt; 2">         (4a)
      In der Arche gibt es mehr als zwei Tiere dieser Art.</report>
      <report test="count(parent::*/arc:tier[arc:art=current()/arc:art]) &lt; 2"> (4b)
      In dieser Unterkunft gibt es weniger als zwei Tiere dieser Art.
      </report>
      <assert test="count(parent::*/arc:tier[arc:art=current()/arc:art][@geschlecht='männlich']) = 1"> (4c)
      Ein Paar muss immer aus einem Männchen und einem Weibchen bestehen.
      </assert>
    </rule>
  </pattern>
 
  <pattern>
    <rule context="arc:zimmer">                                                   (5)
      <report test="count(arc:tier) &gt; 6">
      Noah, bringst du zu viele Tiere in einem Zimmer unter, könnte sich das
      schlecht auf die Zimmergemeinschaft auswirken! Du solltest nicht mehr 
      als 6 Tiere in einem Zimmer unterbringen.
      </report>
    </rule>
  </pattern>
</schema>
(1) Für das Reproduktionsalter muss zwischen männlichen und weiblichen Tieren unterschieden werden, da das maximale Reproduktionsalter für männliche Tiere in <männlich>-Elementen angegeben wird und für die Weibchen in <weiblich>-Elementen.
(a) Der Kontextknoten wird auf das Element <tier> gesetzt, da für jedes Tier das Alter überprüft werden muss.
(b) Die Tests, die hier definiert wurden, vergleichen das jeweilige Alter der Tiere mit dem entsprechenden Alter aus dem <maxReproduktionsalter>-Container. Hierzu wird das <tier_art>-Element ausgewählt, das ein <name>-Element enthält, das dem <art>-Element des Kontextknotens entspricht. In dem entsprechenden <tier_art>-Element wird nun entweder aus dem <männlich>- oder aus dem <weiblich>-Element das maximale Reproduktionsalter entnommen. Da hier kein Datentyp festgelegt wurde, jedoch zwei Zahlen miteinander verglichen werden sollen, müssen beide mit der Funktion number() in einen numerischen Wert umgewandelt werden.
(2) Die Nutzlast ist im Element <nutzlast> angegeben. Das Einhalten der Nutzlast muss nur einmal überprüft werden, weshalb als Kontextknoten das Element <nutzlast> ausgewählt wurde.
(a) Für diesen Test werden nun alle <gewicht>-Elemente des Dokumentes aufsummiert und es wird geprüft, ob die Summe kleiner ist als der Wert von <nutzlast>.
(3) Dieses Pattern haben wir bereits ausführlich behandelt.
 
(4) Diese Regel überprüft für jedes Tier mit einer Kombination aus drei Tests, dass von dieser Art nicht mehr als ein Paar auf der Arche ist, dieses im gleichen Zimmer untergebracht ist und aus einem Weibchen und einem Männchen besteht.
(a) Dieser Test zählt (mit der Funktion count ()) alle Tiere, die das gleiche <art>-Element enthalten wie der Kontextknoten. Der Test ist so formuliert, dass das Ergebnis nicht größer als zwei sein darf. So sorgt der Test dafür, dass maximal zwei Tiere einer Art in der Arche untergebracht wurden.
(b) Im zweiten Test wird überprüft, ob mindestens zwei Tiere dieser Art im gleichen Zimmer untergebracht wurden. Da der vorherige Test bereits überprüft, dass nicht mehr als zwei Tiere dieser Art in der gesamten Arche vorkommen, ergibt die Kombination daraus, dass genau ein Paar im gleichen Zimmer untergebracht werden muss.
(c) Beim dritten Test verwenden wir eine Voraussetzung, die in Kombination mit den anderen Tests überprüft, ob es sich bei dem Paar um ein Weibchen und ein Männchen handelt.
(5) Diese Regel prüft alle <zimmer>-Elemente. Der Test zählt für jedes Zimmer die Anzahl der Tiere und überprüft, ob mehr als sechs <tier>-Elemente enthalten sind.

   

<< zurück>> weiter

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Schematron bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © dpunkt.verlag GmbH 2011
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken. Ansonsten unterliegt dieses Kapitel aus dem Buch "Schematron - Effiziente Business Rules für XML-Dokumente" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, fon 06221-14830, fax 06221-148399, hallo(at)dpunkt.de