Mittwoch, 23. Mai 2012


Artikel

Juli 2009 | Artikel

Über die Eignung von Schema-Sprachen zur Prüfung von XML-Dokumenten Fortsetzung, Teil 3

Teil 1   Teil 2   Teil 3   Teil 4   

Mithilfe der Elemente und werden die eigentlichen Tests formuliert, mit denen die zuvor ausgewählten Knoten überprüft werden sollen. Ein -Element beschreibt eine Zusicherung in Form einer positiven Bedingung, die von den ausgewählten Knoten eingehalten werden soll. Das -Element beschreibt dagegen einen Fehlerzustand in Form einer negativen Bedingung. Die Zusicherungen und Fehlerzustände werden in Form von booleschen Ausdrücken formuliert, indem über das Attribut test ein XPath-Ausdruck auf den Kontextknoten angewendet wird. Adressiert ein Knotentest mindestens einen Knoten, erfolgt gemäß XPATH eine Typkonvertierung in den booleschen Rückgabewert true, anderenfalls wird der Wert false zurückgegeben.

Neben dem Attribut test können die Elemente und auch Text enthalten, der im Fall eines Fehlers als Meldung ausgegeben wird. Dies ist ein entscheidender Vorteil gegenüber anderen Validierungssprachen, bei denen die Fehlermeldungen vom validierenden Parser generiert werden. Automatisch erzeugte Hinweise können besonders für einen Laien sehr verwirrend sein, weil sie oft unverständliche Formulierungen enthalten. Mit Schematron ist es dagegen möglich, dem Anwender konkrete, auf das vorliegende Problem zugeschnittene Handlungsanweisungen zu geben. Mit diesen fünf Elementen sind wir nun in der Lage, die eingangs eingeführte Problemstellung der Fußnotenverschachtelung mit einem einfachen Schematron-Schema zu lösen:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
  3. <sch:pattern name="Rekursionen">
  4. (1) <sch:rule context="footnote">
  5. (2) <sch:report test=".//footnote">
  6. Geschachtelte Fußnoten sind nicht erlaubt.
  7. </sch:report>
  8. </sch:rule>
  9. </sch:pattern>
  10. </sch:schema>

Der erste Ausdruck (1) legt den Kontextknoten auf alle footnote-Elemente. Der zweite Ausdruck (2) testet den Kontextknoten und gibt je nach Testergebnis einen booleschen Wahrheitswert zurück. Der Knotentest .//footnote überprüft demnach, ob innerhalb eines footnote-Elements weitere footnote-Elemente existieren. Da der Ausdruck in einem -Element steht, wird die Fehlermeldung dann ausgegeben, wenn der boolesche Ausdruck den Wert true zurückgibt.

Weitere Beispiele

Die Einsatzgebiete von Schematron sind nicht auf Anwendungen aus dem Bereich der Dokumenterstellung beschränkt. Auch XML-Anwendungen aus dem Bereich der datenzentrierten Dokumenttypen bieten reichhaltige Einsatzmöglichkeiten. Im folgenden Angebotsschema werden mehrere Produkte mit Anzahl und Einzelpreis aufgelistet:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <angebot>
  3. <produkte>
  4. <produkt>
  5. <produktId>PRO000001</produktId>
  6. <name>Toner 01 Schwarz</name>
  7. <anzahl>2</anzahl>
  8. <preis>46.00</preis>
  9. </produkt>
  10. <produkt>
  11. <produktId>PRO000002</produktId>
  12. <name>Toner 01 Gelb</name>
  13. <anzahl>1</anzahl>
  14. <preis>43.33</preis>
  15. </produkt>
  16. <produkt>
  17. <produktId>PRO000003</produktId>
  18. <name>Toner 01 Cyan</name>
  19. <anzahl>5</anzahl>
  20. <preis>48.00</preis>
  21. </produkt>
  22. <produkt>
  23. <produktId>PRO000004</produktId>
  24. <name>Toner 02 Schwarz</name>
  25. <anzahl>2</anzahl>
  26. <preis>28.33</preis>
  27. </produkt>
  28. </produkte>
  29. <gesamtpreis>431.98</gesamtpreis>
  30. </angebot>

In diesem extrem vereinfachten Angebotsszenario gibt es mehrere potenzielle Fehlerquellen. Ein mögliches Problemfeld kann die korrekte Berechnung der Preise sein. Eine mögliche Regel wäre: Das Element muss der Summe aller angebotenen Produktpreise, multipliziert mit deren Anzahl, entsprechen. Das Schematron zur Überprüfung dieser Businessregel lautet:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
  3. <pattern>
  4. <rule context="angebot">
  5. <assert test="
  6. sum(
  7. for $item in produkte/produkt
  8. return $item/anzahl * $item/preis
  9. ) = gesamtpreis">
  10. Korrekter Gesamtpreis:
  11. <value-of select="sum(for $item in produkte/produkt return $item/anzahl * $item/preis)"/>
  12. </assert>
  13. </rule>
  14. </pattern>
  15. </schema>

Durch die Möglichkeit, mit XPath 2.0 for-Schleifen zu formulieren, lässt sich in einem Ausdruck die Summe aller Einzelpositionen ermitteln und mit dem Gesamtpreis vergleichen. Sollte wie im obigen Beispiel die Gesamtsumme nicht mit den Summen der Einzelpositionen übereinstimmen, kann mithilfe des Ausdrucks die korrekte Summe in der Fehlermeldung ausgegeben werden.

Teil 1   Teil 2   Teil 3   Teil 4   

Kommentare

Gravatar Stephan Zehrer 27.07.2009
um 22:51 Uhr
Ich versuche gerade das "ISO Schematron" in mein Weltbild unterzubringen. Ihr redet doch von nichts anderem als von einer Ontology oder?
Also warum nocht RDF, RDFS, und OWL verwenden?
#zitieren