Validierung, erweitert

Der erste Schritt nach dem Schreiben, hin zur Publikation, ist die Validierung. Traditionell ein manueller Prozess, in dem die abgelieferten Manuskriptdateien gegen die Vorgaben abgeprüft wurden. Die Prüfung umfasst dabei nicht nur das Manuskript, sondern auch die beigelegten Artefakte, seien es Bilder oder andere Medien.

Beschäftigt man sich mit der XML-basierten Publikation, dann stößt man schnell darauf, dass in diesem Bereich Validierung meist sehr speziell verstanden wird. Man bezieht sich nämlich meist nur auf die technische Validierung des Manuskripts gegen das verwendete Schema, sei das DocBook, TEI, DITA oder etwas eigenes.

Diese XML-Validierung ist unbedingt notwendig, um die nachfolgenden Verarbeitungsschritte gegen Fehler abzusichern. Sie kann über Validatoren automatisiert werden. Das kann zum Beispiel mit Jing passieren, einem Validator der die Schemasprachen Relax NG und Schematron versteht.

Ein Beispiel anhand eines sehr kurzen DocBook-Artikels:

<article xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink" 
         version="5.0"
         xml:lang="de">
  <info>
    <title>Ein gültiger DocBook 5-Artikel</title>
  </info>
  <para>
    Neben dem Titel ist mindestens noch ein Absatz oder ein anderes
    Inhaltselemten notwendig, um zu einem gültigen Artikel im Sinne
    des DocBook 5-Schemas zu kommen.
  </para>
</article>


Dann den Validator aufrufen:

java -jar jing/bin/jing.jar docbook/docbook.nvdl src/artikel1.xml

Der Jing-Aufruf endet ohne Fehlermeldung. Mit einem Titel und mindestens einem Absatz ist der DocBook-Artikel gegenüber dem veröffentlichten DocBook-Schema gültig. Das DocBook-Schema ist aber sehr flexibel, um möglichst viele Einsatzszenarien abzudecken. So habe ich als Autor selbst in diesem kurzen Dokument eine Wahlmöglichkeit. Ich kann den Titel allein stehen lassen, oder ihn zusammen mit anderen Meta-Angaben in einem Info-Element unterbringen. Also

<article xmlns="http://docbook.org/ns/docbook" ...>
  <title>Ein gültiger DocBook 5-Artikel</title>

oder

<article xmlns="http://docbook.org/ns/docbook" ...>
  <info>
    <title>Ein gültiger DocBook 5-Artikel</title>
  </info>

Beide Ansätze wären gegenüber dem Schema gültig. Was aber, wenn ich nun nur noch eine Möglichkeit zulassen möchte? Weil ich meinen Dokumentstruktur standardisieren möchte, oder weil ich die nachfolgenden Verarbeitungsschritte vereinfachen möchte.

Es bieten sich zwei Möglichkeiten an, um solche Hausstandards umzusetzen:

  1. Anpassung des Schemas
  2. Erweiterte Validierung

Variante 1, die Anpassung des Schemas (siehe DocBook 5: The Definitive Guide, Kapitel I.5 Customizing DocBook) ist vergleichsweise unaufwendig möglich. Man kann Strukturelemente hinzufügen oder wegnehmen, oder auch DocBook mit anderen Schemata mischen. Das Vorgehen bringt aber auch einen gewissen Migrationsaufwand mit sich, denn auch Dokument-Schemata entwickeln sich fort, und das Haus-Schema muss dann eben fortlaufend an diese  Änderungen angepasst werden.

Benötigt man solche tiefgreifenden Änderungen nicht, dann würde sich die etwas leichtfüßigere, erweiterte Validierung (Variante 2) anbieten. Eine Möglichkeit dafür wäre die Nutzung von Schematron. Schematron ist eine auf einem ISO-Standard basierende
Sprache, um XML-Dokumente anhand von Mustern und Regeln zu prüfen. Schematron wurde bei der obigen DocBook-Validierung auch schon verwendet, denn in docbook.nvdl wird der Validator angewiesen, das Quelldokument zuerst anhand des Relax NG-Schemas zu prüfen, und dann zusätzlich gegen Schematron-Regeln. Der Grund dafür ist, dass eine primär auf Dokument-Strukturen ausgerichtete Schemasprache wie Relax NG nicht alle Aspekte des DocBook-Standards prüfen kann.

Mit Schematron kann man beliebige Muster in einem Dokument abtesten und berichten. Diese Technologie bietet, wie wir gleich sehen werden, eine einfache Möglichkeit, Hausstandards ohne großen Aufwand automatisiert zu testen.

Wenn ich also nun festlegen möchte, dass in meinen Dokumenten der Titel nur alleinstehend, nicht in einem Info-Element, erscheinen darf, könnte ich das so formulieren:

<?xml version="1.0" encoding="utf-8"?>
<s:schema xmlns:s="http://www.ascc.net/xml/schematron"
	  xmlns:db="http://docbook.org/ns/docbook">
  <s:ns prefix="db" uri="http://docbook.org/ns/docbook"/>

   <s:pattern name="Nur Titel außerhalb von info">
      <s:rule context="db:article/db:info">
         <s:assert test="not(.//db:title)">
	   Der Titel darf nicht im Info-Element erscheinen.
	 </s:assert>
      </s:rule>
   </s:pattern>

</s:schema>

Ich lege ein Muster (pattern) fest, das ein oder mehrere Regeln (rule) enthalten, die wiederum Tests enthalten. Der Regelkontext (s:rule context) sagt dabei aus, auf welchen Teil eines Dokuments sich die enthaltenen Tests beziehen. In diesem Beispiel also auf Info-Blöcke innerhalb von Artikeln.

Der Test prüft einfach, ob sich dort ein Titel-Element findet, und gibt dann die angegebene Fehlermeldung aus. Wie gesagt, das ist kein DocBook-Fehler, denn es handelt sich ja auch hier um ein gültiges DocBook-Dokument. Die Struktur würde aber gegen unsere Hausregeln verstoßen.

java -jar jing/bin/jing.jar docbook/docbook.nvdl src/artikel1.xml
java -jar jing/bin/jing.jar mdb.sch src/artikel1.xml

Da das Dokument also nach wie vor technisch in Ordnung ist, würde der erste Jing-Aufruf keinen Fehler erzeugen. Der zweite Aufruf mit unseren Hausregeln aber schon:

src/artikel1.xml:5: error: assertion failed:
  Der Titel darf nicht im Info-Element erscheinen.

In Zeile 5 unseres Dokuments gibt es also ein Probleme. Wenn ich das Titelelement nun vor den Info-Block schiebe, sind unsere Hausregeln erfüllt, das Dokument gültig.

<article xmlns="http://docbook.org/ns/docbook" ...>
  <title>Ein gültiger DocBook 5-Artikel</title>
  <info>

Ohne viel Aufwand haben wir also eine Prüfung automatisiert, die über die rein technische XML-Validierung am Schema hinausgeht.

Genauso könnte ich nun zum Beispiel festlegen, dass in jedem Artikel mindestens ein Autor und der bearbeitende Redakteur genannt werden müssen:

   <s:pattern name="Autor und Redakteur müssen angegeben werden">
      <s:rule context="db:info">
         <s:assert test=".//db:authorgroup/db:author">
	   Es muss mindestens ein Autor genannt werden.
	 </s:assert>
         <s:assert test=".//db:authorgroup/db:editor">
	   Es muss mindestens ein Redakteur genannt werden.
	 </s:assert>
      </s:rule>
   </s:pattern>

Füge ich diese Regel mit zwei Tests hinzu, kommen sofort die erwarteten Fehlermeldungen:

src/artikel2.xml:6: error: assertion failed:
  Es muss mindestens ein Autor genannt werden.
src/artikel2.xml:6: error: assertion failed:
  Es muss mindestens ein Redakteur genannt werden.

Nur wenn ich die Angaben auch hinzufüge, sind unsere Hausregeln befriedigt:

<article xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="de">

  <title>Ein gültiger DocBook 5-Artikel</title>
  <info>
    <authorgroup>
      <author>
	<personname>
	  <firstname>Sabine</firstname><surname>Mustermann</surname>
	</personname>
      </author>
      <editor>
	<personname>
	  <firstname>Karl</firstname><surname>Mustermann</surname>
	</personname>
      </editor>
    </authorgroup>
  </info>
  <para>

Schematron kann nicht nur das Vorhandensein von Elementen überprüfen, sondern auch zum Beispiel Inhalte. Da es auf XSLT beruht, stehen einem alle Möglichkeiten von XSLT 1.0 bzw. 2.0 offen.

Damit hätten wir also das angelieferte Manuskript auf Herz und Nieren getestet. Bleiben die anderen Artefakte einer Lieferung. Hier kann man einfach Skripte einsetzen, um immer wiederkehrende Prüfungen zu automatisieren, also zum Beispiel:

  • gibt es für jedes Bildelement im Manuskript auch eine passende
    Bilddatei?
  • haben die Bilddateien die gewünschten Formate (Vektor, Bitmap) und
    Größen?

Skriptsprachen wie Ruby, Python, Perl bieten viele Bibliotheken, um Mediendateien aller Art zu analysieren oder zu transformieren. Es gibt also keinen Grund aufwendige, manuelle Prüfprozesse beizubehalten.