La solution

<schema xmlns="http://purl.oclc.org/dsdl/schematron">
  <ns uri="http://www.schematron.info/arche" prefix="arc"/>
  <pattern>                                                                 (1)
    <rule context="arc:animal[@sexe='male']">                               (1a)
      <report test="number(arc:age) &gt; number(//arc:maxAgeReproduction/arc:animal_espece[arc:nom=current()/arc:espece]/arc:male)"> (1b)
      Le mâle est trop âgé, Noé! Il ne pourra plus se reproduire.
      Veille à la sélection naturelle.</report>
    </rule>
    <rule context="arc:animal[@sexe='femelle']">                            (1a)
      <report test="number(arc:age) &gt; number(//arc:maxAgeReproduction/arc:animal_espece[arc:nom=current()/arc:espece]/arc:femelle)"> (1b)
      La femelle est trop âgé, Noé! Elle ne pourra plus se reproduire.
      Veille à la sélection narurelle.</report>
    </rule>
  </pattern>
 
  <pattern>
    <rule context="arc:charge">                                                 (2)
      <report test=". &lt; sum(//arc:poids)">                                   (2a)
      Noé, tu as trop d'animaux à bord. Le chargement dépasse le poids maximal
      autorisé dans l'arche.</report>
    </rule>
  </pattern>

  <pattern>                                                                     (3)
    <rule context="arc:animal[@carnivore='oui']">
      <report test="parent::*/arc:animal[@carnivore='non']">
      Il y a des carnivores et des herbivores dans un même compartiment. 
      Les animaux ne sont pas des ressources alimentaires!</report>
      <report test="parent::*/arc:animal/arc:poid &lt; (arc:poids div 2)">
      Noé, ce carnivore est trop fort (lourd) pour ses compagnons de chambrée.
      Il pourrait les utiliser comme un ressource alimentaire.</report>
    </rule>
    <rule context="arc:animal">
      <report test="parent::*/arc:animal/arc:poids &lt; (arc:poids div 10)">
      Noé, l'animal est trop lourd pour ces compagnons de chambrée! 
      Il pourrait en piétiner un.</report>
    </rule>
  </pattern>
 
  <pattern>
    <rule context="arc:animal">                                                           (4)
      <report test="count(//arc:animal[arc:espece=current()/arc:espece]) &gt; 2">         (4a)
      Dans l'arche, se trouvent plus de deux animaux de cette espèce.</report>
      <report test="count(parent::*/arc:animal[arc:espece=current()/arc:espece]) &lt; 2"> (4b)
      Dans ce compartiment, se trouvent moins de deux animaux de cette espèce.
      </report>
      <assert test="count(parent::*/arc:animal[arc:espece=current()/arc:espece][@sexe='male']) = 1"> (4c)
      Un couple est toujours composé d'un mâle et d'une femelle.
      </assert>
    </rule>
  </pattern>
 
  <pattern>
    <rule context="arc:chambre">                                                          (5)
      <report test="count(arc:chambre) &gt; 6">
      Noé, si tu places trop d'animaux dans un même compartiment, il se peut que cela ait
      des conséquences néfastes sur la vie en communauté! Tu ne devrais pas mettre plus 
      de 6 animaux dans un même compartiment.
      </report>
    </rule>
  </pattern>
</schema>

 

(1) Une distinction doit être opérée entre les mâles et les femelles en ce qui concerne l'âge de reproduction, c'est pourquoi l'âge maximum de reproduction pour les mâles sera indiqué par l'élément <male> et pour les femelles par l'élément <femelle>.
(a) Le nœud de contexte porte sur l'élément <animal>, parce que l'âge de chaque animal doit être vérifié.
(b) Les tests définis ici comparent l'âge des animaux avec l'âge du conteneur <maxAgeReproduction>. À cet effet, on choisit l'élément <animal_espece> qui contient un élément <nom>, qui à son tour doit correspondre à l'élément <espece> du nœud de contexte. Dans l'élément <animal_espece> correspondant, l'âge maximum de reproduction est déduit soit de l'élément <male>, soit de l'élément <femelle>. Puisqu'il n'y a ici aucun type de données fixé, mais que cependant deux chiffres doivent être comparés entre eux, ces derniers doivent être transformés en une valeur numérique grâce à la fonction number().
 
(2) La charge utile est indiquée par l'élément <charge>. Le respect de la charge utile ne doit être vérifié qu'une fois, c'est la raison pour laquelle l'élément <charge> a été choisi comme nœud de contexte.
(a) Pour ce test tous les éléments <poids> du document sont additionnés et on vérifie que cette somme soit plus petite que la valeur de <charge>.
 
(3) Ce pattern a été déjà traité de manière détaillée.
(4) Cette règle vérifie pour chaque animal à l'aide d'une combinaison de trois tests, s'il y a dans l'arche plus d'un couple d'une même espèce, s'il a été placé dans le même compartiment et s'il se compose d'un mâle et d'une femelle.
(a) Ce test comptabilise (à l'aide de la fonction count()) tous les animaux qui contiennent le même élément <espece> que le nœud de contexte. Le test est formulé de telle façon, que le résultat ne doit pas être supérieur à deux. C´est ainsi que le test veille à ce que pas plus de deux animaux d'une même espèce ne soient embarqués au bord de l´arche.
(b) Le deuxième test contrôle, si au moins deux animaux de cette espèce ont été placés dans le même compartiment. Étant donné que le test précédent a déjà vérifié que pas plus de deux animaux de cette espèce se trouvent dans l'arche, on en conclut qu'un couple, très exactement, a été placé dans le même compartiment.
(c) À l'occasion du troisième test, nous utilisons une condition qui en combinaison avec les autres tests vérifie si parmi le couple se trouvent bien un mâle et une femelle.
 
(5) Cette règle vérifie tous les éléments <chambre>. Le test compte le nombre d'animaux dans chaque chambre et vérifie si plus de six éléments <animal> ont été détectés.
<< précédent  

 

 

 


Copyright © dpunkt.verlag GmbH 2011
Vous pouvez imprimer cette version en ligne pour un usage privé. Par ailleurs, ce chapitre du livre "Schematron - Effiziente Business Rules für XML-Dokumente" est soumis aux mêmes clauses prévues pour la version papier : L'intégralité de l'oeuvre est protégée par les droits d'auteurs. Tous droits réservés y compris la copie, la traduction, la reproduction sur microfilm, tout comme l'enregistrement et le traitement dans des systèmes électroniques.

dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, téléphone + 49 (0)6221-14830, fax + 49 (0)6221-148399, hallo(at)dpunkt.de