Verbessern der Gültigkeitsprüfung von XML-Dokumenten mit Schematron

Von Dare Obasanjo

Dare Obasanjo erläutert, wie Sie mit der XML-Überprüfungssprache Schematron Einschränkungen für XML-Dokumente erzwingen können, die über die Möglichkeiten von W3C XML Schema hinausgehen. Dieser Artikel enthält auch Links zu englischsprachigen Seiten.

Laden Sie hier das Codebeispiel für diesen Artikel herunter.

* * *

Auf dieser Seite

Einführung Einführung
Die sechs grundlegenden Elemente von Schematron Die sechs grundlegenden Elemente von Schematron
Kombinieren von Schematron mit der W3C XML Schema-Gültigkeitsprüfung Kombinieren von Schematron mit der W3C XML Schema-Gültigkeitsprüfung
Verwenden von Schematron in .NET Framework Verwenden von Schematron in .NET Framework
Schlussfolgerung Schlussfolgerung

Einführung

Mit einem XML-Schema wird die Struktur eines XML-Dokuments beschrieben. Dabei werden die gültigen Elemente, die in diesem Dokument verwendet werden können, deren mögliche Reihenfolge und eventuelle Einschränkungen für bestimmte Aspekte dieser Elemente festgelegt. Im Laufe der Verbreitung von XML und XML-Schemasprachen entwickelten sich im Bereich der Gültigkeitsprüfung von XML-Dokumenten und XML-Schemas zwei Hauptanwendungsszenarios.

  1. Beschreiben und Erzwingen des Vertrags zwischen XML-Dokument-Producers und -Consumers: Mit XML-Schemas lässt sich auf verhältnismäßig einfache und für Computer lesbare Art und Weise beschreiben, wie ein gültiges XML-Dokument entsprechend eines bestimmten XML-Vokabulars aufgebaut ist. Somit kann ein Schema auch als "Vertrag" zwischen dem Producer und dem Consumer eines XML-Dokuments betrachtet werden. Normalerweise stellt der Consumer sicher, dass das vom Producer empfangene XML-Dokument den Vertrag erfüllt, indem er die Gültigkeit des Dokuments anhand des Schemas überprüft. Die obige Beschreibung deckt einen großen Bereich von XML-Anwendungsszenarios ab, von Geschäftsentitäten, die XML-Dokumente austauschen, bis zu Anwendungen, die XML-Konfigurationsdateien verwenden, und vieles mehr.

  2. Erstellen der Basis für die Verarbeitung und Speicherung von typisierten, mit XML-Dokumenten dargestellten Daten: Mit der steigenden Beliebtheit von XML als Mittel zur Darstellung strukturierter und streng typisierter Daten, z. B. dem Inhalt einer relationalen Datenbank oder Programmobjekten, ergab sich auch die Notwendigkeit, die Datentypen in einem XML-Dokument beschreiben zu können. Dies führte zur Entwicklung von XML-Schemasprachen, die Mechanismen zur Umwandlung eines XML-Infosatzes in einen Infosatz mit Typangaben, in dem Element- und Attributinformationen mit Typnamen kommentiert werden, zur Verfügung stellen. In der W3C XML Schema Recommendation wird die Erstellung eines Infosatzes mit Typangaben als Folge der Gültigkeitsprüfung von Dokumenten anhand von Schemas beschrieben. Bei der Gültigkeitsprüfung anhand eines W3C XML Schemas wird ein XML-Eingabe-Infosatz in einen Post Schema Validation Infoset (PSVI) umgewandelt, der u. a. Typangaben enthält. Wie die Praxis jedoch gezeigt hat, muss zum Erstellen von Infosätzen mit Typangaben keine vollständige Dokumentüberprüfung durchgeführt werden. Im Allgemeinen führen viele Anwendungen, die streng typisiertes XML mit XML-Schemas erstellen, z. B. XML/Objekt-Zuordnungstechnologien, keine vollständige Dokumentüberprüfung durch.

Die derzeit verbreitetste XML-Schemasprache ist W3C XML Schema Definition (XSD). Obwohl sich XSD für Szenarien mit Infosätzen mit Typangaben eignet, ist es beim Beschreiben von Einschränkungen für die Struktur eines XML-Dokuments ziemlich eingeschränkt. Es gibt viele Beispiele für Situationen, in denen allgemeine Idiome im Entwurf des XML-Vokabulars mit den in W3C XML Schema verfügbaren Einschränkungen nicht ausgedrückt werden können. Die drei im Allgemeinen am häufigsten vermissten Einschränkungen, die mit W3C XML Schema nicht beschrieben werden können, sind die folgenden:

  1. Die Möglichkeit, eine Auswahl an Attributen anzugeben. Beispiel: Ein Element server-status kann entweder über ein Attribut server-uptime oder ein Attribut server-downtime verfügen.

  2. Die Möglichkeit, Elemente und Attribute in Modellgruppen zusammenzufassen. Obwohl Elemente mit Compositors wie xs:sequence, xs:choice und xs:all gruppiert werden können, funktioniert das nicht mit Elementen und Attributen. Beispiel: Es kann keine Auswahl zwischen zwei Sätzen an Elementen und Attributen erstellt werden.

  3. Die Möglichkeit, das Inhaltsmodell abhängig vom Wert eines Elements oder Attributs zu ändern. Beispiel: Wenn das Attribut status den Wert available hat, soll das Element über das untergeordnete Element uptime verfügen, andernfalls über das untergeordnete Element downtime. Einschränkungen dieser Art werden Co-Occurrence Constraints genannt.

Obwohl diese Idiome in XML-Vokabularen oft verwendet werden, ist es nicht möglich, sie mit W3C XML Schema zu beschreiben. Deshalb ist es schwierig, sich beim Erzwingen des Nachrichtenvertrags auf die Schemagültigkeitsprüfung zu verlassen. In diesem Artikel wird beschrieben, wie Sie diese Funktionalität erreichen, indem Sie sie W3C XML Schema mit Schematron erweitern.

 

Die sechs grundlegenden Elemente von Schematron

Die Schematron-Assertionsprache (in Englisch) bietet einen Mechanismus zum Erstellen von Annahmen über die Gültigkeit eines XML-Dokuments mit XPath-Ausdrücken. In einem Schematron-Dokument werden im Allgemeinen die folgenden sechs Elemente verwendet: schema, ns, pattern, rule, assert und report. Der Namespace-URI für die in der Schematron-Assertionsprache verwendeten Elemente ist http://www.ascc.net/xml/schematron.

  1. Das Element <schema> (in Englisch): Das Dokumentelement des Schemas. Dieses Element hat die folgenden untergeordneten Elemente: Das Element title, das den lesbaren Namen des Schemas enthält. Die ns-Elemente, mit denen Namespace/Präfix-Bindungen angegeben werden können, die in den XPath-Ausdrücken im Schema verwendet werden können. Die phase-Elemente, die Gruppen von Mustern beschreiben, die zusammen ausgeführt werden sollen. Die pattern-Elemente, die Gruppen von Regeln enthalten, anhand derer das Dokument überprüft werden kann. Und das Element diagnostics, das ein oder mehrere diagnostic-Elemente enthält, mit denen genauere Fehlermeldungen ermöglicht werden, wenn ein Dokument eine Erklärung nicht erfüllt. Weiterhin verfügt das Element schema über die folgenden Attribute: id, version, schemaVersion, fpi, defaultPhase und icon. Es folgt ein Beispiel für das schema-Element:

        <schema xmlns="http://www.ascc.net/xml/schematron" 
             schemaVersion="1.01" >
       <title>A Schema for Books</title>
       <ns prefix="bk" uri="http://www.example.com/books" />
       <pattern id="authorTests">
         <rule context="bk:book">
           <assert test="count(bk:author)!= 0">
        A book must have at least one author
           </assert>
         </rule>
       </pattern>
       <pattern id="onLoanTests">
         <rule context="bk:book">
           <report test="@on-loan and not(@return-date)">
        Every book that is on loan must have a return date
           </report>
         </rule>
       </pattern>
     </schema>
    
  2. Das Element <ns> (in Englisch): Dies dient der Bindung eines Präfixes an einen Namespace. Diese Bindung kann in den XPath-Ausdrücken in den Elementen pattern, rule und assert verwendet werden. Die Attribute prefix und uri sind erforderlich. Mit diesen werden der Präfix des Namespace und der Name des Namespace definiert, an den der Präfix gebunden ist. Es folgt ein Beispiel für das ns-Element:

    <ns prefix="bk" uri="http://www.example.com/books" />
    
  3. Das Element <pattern> (in Englisch): Ein pattern enthält eine Liste von rule-Elementen. Außerdem verfügt das Element pattern über die folgenden Attribute: id, name, see und icon. Die Hauptfunktion dieses Elements ist die Gruppierung ähnlicher Annahmen, so dass für die verschiedenen Phasen der Gültigkeitsüberprüfung verschiedene Regeln kombiniert werden können. Es folgt ein Beispiel für das pattern-Element:

        <pattern id="authorTests"
      see="http://www.example.com/books/guidelines.html"
      name="Test for non-zero number of authors">
         <rule context="bk:book">
           <assert test="count(bk:author)!= 0">
              A book must have at least one author
           </assert>
         </rule>
       </pattern>
    
  4. Das Element <rule> (in Englisch): Die Elemente assert und report sind untergeordnete Elemente der rule-Elemente. Das rule-Element hat ein Attribut context, das einen XPath-Ausdruck enthält. Für alle Knoten des Eingabedokuments, die dem im Attribut context angegebenen XPath-Ausdruck entsprechen, wird dann anhand der Elemente assert und report der Regel getestet, ob sie die Annahme erfüllen. Eine Regel hat außerdem ein Attribut abstract, mit dem Makros eingeschlossen werden können. Wenn der Wert des Attributs true ist, kann der Inhalt der Regel in anderen rule-Elementen eingeschlossen werden. Ein rule-Element kann über ein oder mehrere extends-Elemente verfügen, die auf eine abstrakte Regel verweisen. Bei der Gültigkeitsprüfung wird das extends-Element einer Regel mit den Inhalten der abstrakten Zielregel ersetzt. Eine Regel kann analog zum key-Element in XSLT auch ein key-Element enthalten, das einen Mechanismus zum Definieren von Querverweisen zwischen Teilen eines Dokuments bietet. Das Element key hat ein Attribut name, mit dem der Schlüssel identifiziert werden kann, und ein Attribut path, das den XPath-Ausdruck zum Vergleichen enthält. Es folgt ein Beispiel für das rule-Element:

        <rule context="bk:book" role="authorCountRule">
           <assert test="count(bk:author)!= 0">
            A book must have at least one author
           </assert>
         </rule>
    
  5. Das Element <assert> (in Englisch): Das Element assert bietet einen Mechanismus zum Testen, ob eine Aussage (d. h. eine Assertion) über das Inhaltsmodell eines Elements wahr ist. Das Attribut test dieses Elements enthält einen XPath-Ausdruck. Wenn das Ergebnis der Konvertierung der Ergebnisse der XPath-Abfrage in einen Booleschen Wert mit der XPath-Funktion boolean() den Wert false ergibt, ist bei der Überprüfung ein Fehler aufgetreten. In diesem Fall wird der Inhalt des assert-Elements als Fehlermeldung ausgegeben. Das assert-Element gestattet gemischte Inhalte für die Fehlermeldungen: Text gespickt mit Elementen. Die meisten Elemente, die als untergeordnete Elemente verwendet werden können, dienen zur Formatierung und sind an HTML angelehnt: p, emph und dir. Außerdem gibt es noch die untergeordneten Elemente name. Bei der Ausgabe der Fehlermeldung wird das Element name mit dem Namen des context-Elements ersetzt. Damit Schemaautoren Fehlermeldungen wiederverwenden können, kann ein assert-Element ein diagnostics-Attribut haben, das auf ein oder mehrere diagnostic-Elemente im diagnostics-Element des Schemas verweist. Dadurch werden beim Auftreten eines Fehlers während der Gültigkeitsprüfung der Inhalt des assert-Elements und der Inhalt des referenzierten diagnostic-Elements ausgegeben. Außerdem verfügt das Element assert über die folgenden Attribute: id, role, subject und icon. Es folgt ein Beispiel für das assert-Element:

    <assert test="count(bk:author)!= 0">
            A book must have at least one author
     </assert>
    
  6. Das Element <report> (in Englisch): Das Element report entspricht bis auf einen entscheidenden Unterschied exakt dem Element assert. Wenn das Konvertierungsergebnis des Attributs test im Resultat der XPath-Abfrage mit der XPath-Funktion boolean() den Wert true ergibt, ist bei der Überprüfung ein Fehler aufgetreten. Es folgt ein Beispiel für das report-Element:

        <report test="@on-loan and not(@return-date)">
       Every book that is on loan must have a return date
      </report>
    

Weitere Informationen über die Elemente in Schematron finden Sie in der ZVON Schematron-Referenz (in Englisch).

 

Kombinieren von Schematron mit der W3C XML Schema-Gültigkeitsprüfung

Ein Problem bei der Gültigkeitsprüfung mit Schematron ist die umständliche Angabe der Struktur eines XML-Dokuments. Im Gegensatz dazu ist dieser Vorgang in W3C XML Schema verhältnismäßig einfach. Jedoch können Sie glücklicherweise Schematron-Regeln in W3C XML Schema (in Englisch) einbetten.

Nach den W3C XML Schema Recommendations ist es Anwendungen gestattet, die Schemaüberprüfung durch Hinzufügen anwendungsspezifischer Daten zu erweitern. Dazu dienen die xs:appinfo-Elemente im xs:annotation-Element eines bestimmten Schemaelements. In diese Erweiterungsblöcke können die pattern-Elemente von Schematron eingebettet werden. Diese lassen sich dann als Teil der Schemaüberprüfung anwenden. Namespaces, die dabei verwendet werden, sollten auf oberster Ebene des Schemas mit ns-Elementen in einer xs:annotation deklariert werden. Im folgenden Beispiel wird ein W3C XML Schema dargestellt, in dem mit eingebetteten Schematron-Regeln Einschränkungen definiert werden, die über die Fähigkeiten von W3C XML Schema hinausgehen. Speziell durch das pattern-Element wird erzwungen, dass beim Vorhandensein des optionalen Attributs on-loan des Elements book auch ein Attribut return-date vorhanden sein muss.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  
    xmlns:sch="http://www.ascc.net/xml/schematron"
    targetNamespace="http://www.example.com/books"
    xmlns:bk="http://www.example.com/books"
    elementFormDefault="qualified" >

  <xs:annotation>
    <xs:appinfo>
     <sch:title>Schematron validation</sch:title>
     <sch:ns prefix="bk" uri="http://www.example.com/books"/>
    </xs:appinfo>
   </xs:annotation>

 <xs:element name="books"> 
  <xs:complexType>
   <xs:sequence>  
    <xs:element name="book" type="bk:bookType" maxOccurs="unbounded">
      <xs:annotation>
       <xs:appinfo>
        <sch:pattern id="onLoanTests">
          <sch:rule context="bk:book">
           <sch:report test="@on-loan and not(@return-date)">
           Every book that is on loan must have a return date
           </sch:report>
          </sch:rule>
        </sch:pattern>
       </xs:appinfo>
      </xs:annotation>
    </xs:element>
   </xs:sequence> 
  </xs:complexType>
 </xs:element>

 <xs:complexType name="bookType">
  <xs:sequence>
   <xs:element name="title" type="xs:string" />
   <xs:element name="author" type="xs:string" />
   <xs:element name="publication-date" type="xs:date" />
  </xs:sequence>
  <xs:attribute name="publisher" type="xs:string" use="required" />
  <xs:attribute name="on-loan" type="xs:string"  use="required" />
  <xs:attribute name="return-date" type="xs:date"  use="required" />
 </xs:complexType>

</xs:schema>

Verwenden von Schematron in .NET Framework

Die Diskussion über die größere Flexibilität, die durch die Verwendung von in XML-Schemas eingebetteten Schematron-Regeln erreicht wird, wäre hinfällig, wenn es keine Möglichkeit gäbe, Schematron im .NET Framework zu verwenden. Es gibt eine Implementierung von Schematron für das .NET Framework, die vom Microsoft XML MVP (Most Valuable Professional), Daniel Cazzulino implementiert wurde: Schematron.NET. Sie stellt Klassen für die Gültigkeitsprüfung von XML-Dokumenten anhand von Schematron-Schemas und XML-Schemas, die eingebettete Schematron-Regeln enthalten, zur Verfügung. Die meisten Benutzer interagieren direkt mit der Schematron.NET-Klasse NMatrix.Schematron.Validator. Es folgt ein Überblick über die API dieser Klasse.

Konstruktoren

  1. Ein überladener Konstruktor, mit dem angegeben werden kann, ob die IXPathNavigable-Instanz, die als Ergebnis des Aufrufs von Validate() zurückgegeben wird, ein XmlDocument oder ein XPathDocument sein soll.

    public Validator(NavigableType type)
    
  2. Ein überladener Konstruktor, der angibt, in welchem Format die Ausgabe erfolgen soll.

    public Validator(OutputFormatting format)
    
  3. Ein überladener Konstruktor, mit dem angegeben werden kann, in welchem Format die Ausgabe erfolgen soll und ob die IXPathNavigable-Instanz, die als Ergebnis des Aufrufs von Validate() zurückgegeben wird, ein XmlDocument oder ein XPathDocument sein soll.

    public Validator(OutputFormatting format, NavigableType type)
    
  4. Der Standardkonstruktor, mit dem festgelegt werden kann, dass XPathDocument von dem IXPathNavigable-Typ ist, der von den Validate()-Methoden zurückgegeben wird, und dass für die Formatierung OutputFormatting.Log verwendet wird.

    public Validator()
    

Eigenschaften

  1. Der Evaluierungskontext.

    public EvaluationContextBase Context { get; set; }
    
  2. Der Typ, der von der Methode Validate() zurückgegeben wird, ist ein XmlDocument oder ein XPathDocument.

    public NavigableType ReturnType { get; set; }
    
  3. Das Formatierungsobjekt, das zum Erzeugen der Ausgabe der Gültigkeitsprüfung verwendet wird.

    public IFormatter Formatter {get; set;}
    
  4. Ein Bezeichner für das phase-Element, dessen Muster bei der Gültigkeitsprüfung ausgewertet werden sollen.

    public string Phase {get; set;}
    

Methoden

  1. Fügt dem Schemasatz des Validators eine Datei mit einem XML-Schema oder mit Schematron-Regeln hinzu.

    public void AddSchema(XmlSchema 
    schema)
     public void AddSchema(Schema schema)
     public void AddSchema(Stream input)
     public void AddSchema(TextReader reader)
     public void AddSchema(XmlReader reader)
     public void AddSchema(string uri schema)
    
  2. Fügt dem Schemasatz des Validators eine Auflistung von Dateien mit XML-Schemas oder Schematron-Regeln hinzu.

    public void AddSchemas(XmlSchemaCollection schemas)
     public void AddSchemas(SchemaCollection schemas)
    
  3. Überprüft das Eingabedokument anhand der entsprechenden Schematron-Regeln. Wenn die Schematron-Regeln in ein XML-Schema eingebettet sind, wird keine XSD-Gültigkeitsprüfung durchgeführt.

    public void ValidateSchematron(IXPathNavigable source)
     public void ValidateSchematron(XPathNavigator nav)
    
  4. Überprüft das Eingabedokument anhand der entsprechenden Schemas. Wenn das entsprechende Schema ein XML-Schema mit eingebetteten Schematron-Regeln ist, werden eine Schematron- und eine XSD-Gültigkeitsprüfung durchgeführt.

    public IXPathNavigable Validate(string uri)
     public IXPathNavigable Validate(Stream input)
     public IXPathNavigable Validate(XmlReader reader)
     public IXPathNavigable Validate(TextReader reader)
    

Beispiel
Im folgenden Codebeispiel wird die Datei books.xml anhand des XML-Schemas aus dem Abschnitt Kombinieren von Schematron mit der W3C XML Schema-Gültigkeitsprüfung dieses Artikels überprüft.

using System;
using System.Xml;
using NMatrix.Schematron;

class Program{

  public static void Main(string[] args){

    try{
     Validator validator = new Validator();
     validator.AddSchema("books.xsd"); 
     validator.Validate(new XmlTextReader("books.xml"));
 
    }catch(Exception e){
      Console.WriteLine(e);
    }
  }
}

 

Schlussfolgerung

In diesem Artikel wird beschrieben, dass durch die Kombination von Schematron und W3C XML Schema die besten Ergebnisse zu erzielen sind. Sie können typisierte XML-Dokumente mit XSD erstellen und trotzdem umfangreiche Gültigkeitsüberprüfungen für die Geschäftsregeln durchführen, die Sie in der deklarativen Form der Schemasprache angeben. Entwickler, die .NET Framework verwenden, können schon heute von Schematron profitieren. Sie finden Schematron.NET auf SourceForge oder in der Assembly im Download für diesen Artikel.

Fangen Sie noch heute an, Schematron für Ihre XML-Gültigkeitsprüfungen zu verwenden. Schematron bietet das Beste aus beiden Welten!