Schema-Inklusion mit Redefinition

(Auszug aus "XML Schema" von Eric van der Vlist)

Inklusion gibt keine Mittel an die Hand, die übernommenen Definitionen zu modifizieren. Da sie andererseits nach der Importierung als globale Definitionen betrachtet werden, können sie anschließend auch nicht mehr verändert werden. W3C XML Schema bietet aber die Möglichkeit, von globalen Typen und Gruppendefinitionen während der Einbindung abzuleiten, wobei der Name nach der Einbindung weiterhin derselbe ist. Die Semantik dieser Redefinition lautet also: »Nimm diese Definition statt derjenigen, die du in dem eingebundenen Schema gefunden hast, aber stelle sicher, daß es sich um eine gültige Ableitung handelt, damit Anwendungen durch die Änderung nicht allzu stark überrascht werden.« Implementiert wird dies durch das Element xs:redefine zusammen mit einem schemaLocation-Attribut (genau wie bei xs:include). Seine Kinder sind Komponentendefinitionen, die die in dem eingebundenen Schema angetroffenen Definitionen ersetzen. Die Definitionen, die nicht in dem Element xs:redefine aufgeführt werden, werden unverändert übernommen. Das bedeutet, daß ein xs:redefine ohne Kindelemente zu einem xs:include vollständig äquivalent ist.

Anzumerken ist hier, daß die Auswirkungen der Redefinition global für das sich ergebende Schema gelten. Verweise auf redefinierte Komponenten sind von den an diesen Komponenten vorgenommenen Veränderungen ausnahmslos betroffen, selbst wenn sie in dem redefinierten Schema vorgenommen werden.

Redefinition einfacher und komplexer Typen

Einfache und komplexe Typen werden redefiniert, indem von ihnen innerhalb des Elements xs:redefine abgeleitet wird (bei einfachen Typen durch Einschränkung, bei komplexen Typen durch Einschränkung oder durch Erweiterung). Wir können dies auf unser voriges Beispiel anwenden. Die Definition von bookTmp wird zur Zeit verwendet, um das Element book durch Ableitung zu beschreiben:

<xs:element name="book">
   <xs:complexType>
      <xs:complexContent>
         <xs:restriction base="bookTmp">
            <xs:sequence>
               <xs:element ref="isbn"/>
               <xs:element ref="title"/>
               <xs:element ref="author" minOccurs="0" maxOccurs="unbounded"/>
               <xs:element ref="character" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:attribute name="id" type="bookID"/>
            <xs:attribute ref="available"/>
         </xs:restriction>
      </xs:complexContent>
   </xs:complexType>
</xs:element>

Statt dessen können wir auch den komplexen Typ book redefinieren. Das neue Schema zur Definition der komplexen Typen lautet dann:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:complexType name="elementWithID">
      <xs:attribute ref="id"/>
   </xs:complexType>
   <xs:complexType name="book">
      <xs:complexContent>
         <xs:extension base="elementWithID">
            <xs:sequence>
               <xs:element ref="isbn"/>
               <xs:element ref="title"/>
               <xs:element ref="author" minOccurs="0" maxOccurs="unbounded"/>
               <xs:element ref="character" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:attribute ref="available"/>
         </xs:extension>
      </xs:complexContent>
   </xs:complexType>
   <xs:complexType name="personType">
      <xs:complexContent>
         <xs:extension base="elementWithID">
            <xs:sequence>
               <xs:element ref="name"/>
               <xs:element ref="born"/>
               <xs:element ref="dead" minOccurs="0"/>
               <xs:element ref="qualification" minOccurs="0"/>
            </xs:sequence>
         </xs:extension>
      </xs:complexContent>
   </xs:complexType>
</xs:schema>

Die Redefinition – beachten Sie, wie ein komplexer Typ book mit Hilfe eines Basistyps desselben Namens redefiniert wird, was sonst stets verboten wäre – und die Verwendung des Elements book sehen dann so aus:

<xs:redefine schemaLocation="complex-types2.xsd">
   <xs:complexType name="book">
      <xs:complexContent>
         <xs:restriction base="book">
            <xs:sequence>
               <xs:element ref="isbn"/>
               <xs:element ref="title"/>
               <xs:element ref="author" minOccurs="0" maxOccurs="unbounded"/>
               <xs:element ref="character" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:attribute name="id" type="bookID"/>
            <xs:attribute ref="available"/>
         </xs:restriction>
      </xs:complexContent>
   </xs:complexType>
</xs:redefine>
<xs:element name="book" type="book"/>

Redefinition von Element- und Attributgruppen

Die Redefinition komplexer und einfacher Typen scheint ganz natürlich und dürfte keine große Überraschung darstellen, denn sie baut auf dem auf, was wir in den vorangegangenen Kapiteln genau besprochen haben. Das neue an xs:redefine ist, daß Element- und Attributgruppen – von denen nicht abgeleitet werden kann – ebenfalls redefiniert werden können. Die Redefinition von Element- und Attributgruppen wird ohne zusätzliches Schema-Element erreicht: Eine Gruppenredefinition, die einen Verweis auf sich selbst enthält, wird als Erweiterung betrachtet, anderenfalls als Einschränkung. Diese beiden Methoden haben ihre eigenen Regeln und eigene Semantik, die den Regeln und der Semantik der Ableitung komplexer Typen ähnlich, aber nicht gleich sind. Sie verdienen eine gesonderte Beschreibung. Wie wir sehen werden, sind die Grundprinzipien dieselben, und die Asymmetrie zwischen Erweiterung und Einschränkung wird bei Gruppenredefinitionen beibehalten.

Erweiterung

Eine Gruppen erweiterung wird realisiert, indem man die Gruppe irgendwo in der Redefinition referenziert. Die Semantik ist daher ähnlich derjenigen der Ableitung durch Erweiterung bei komplexen Typen komplexen Inhalts (neuer Inhalt wird dem Basistyp hinzugefügt), bietet jedoch mehr Flexibilität. Der Ort, an dem der Inhalt des Basistyps hinzugefügt wird, kann während der Gruppenerweiterung gewählt werden. Dies steht im Gegensatz zur Erweiterung eines komplexen Typs komplexen Inhalts, wo der neue Inhalt immer im Anschluß an den des Basistyps hinzugefügt wird. Nehmen wir beispielsweise eine Gruppendefinition wie die folgende an:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:group name="character">
      <xs:sequence>
         <xs:element ref="born"/>
         <xs:element ref="qualification"/>
      </xs:sequence>
   </xs:group>
</xs:schema>

Wir können bei der Redefinition das Element name, das am Anfang des Inhalts fehlt, hinzufügen:

<xs:redefine schemaLocation="character-group.xsd">
   <xs:group name="character">
      <xs:sequence>
         <xs:element ref="name"/>
         <xs:group ref="character"/>
      </xs:sequence>
   </xs:group>
</xs:redefine>
<xs:element name="character">
   <xs:complexType>
      <xs:group ref="character"/>
      <xs:attribute ref="id"/>
   </xs:complexType>
</xs:element>

Den Einfügungspunkt für den Inhalt der Basisgruppe konnten wir so wählen, daß er hinter dem Element name liegt. Dies ist eine Verbesserung gegenüber der Ableitung bei komplexen Typen komplexen Inhalts.

Diese Methode der Erweiterung von Element- oder Attributgruppen ist in der Recommendation eindeutig nicht ausreichend spezifiziert und sollte nur in der einfachsten Form verwendet werden, um Problemen bei der Interoperabilität aus dem Weg zu gehen. Die Recommendation legt fest, daß die Attribute minOccurs und maxOccurs des Verweises genau eins sein müssen, was den Wunsch anzeigt, den Inhalt der Basisgruppe während einer Erweiterung genau einmal aufzunehmen. Die Formulierung der Recommendation verbietet jedoch nicht die Einbindung dieser Referenz in einem Zweig, der eine andere Auftretenshäufigkeit hat:

<xs:redefine schemaLocation="bar.xsd">
   <xs:group name="foo">
      <xs:sequence>
         <xs:sequence minOccurs="0">
            <xs:group ref="foo"/>
         </xs:sequence>
         <xs:element ref="bar"/>
      </xs:sequence>
   </xs:group>
</xs:redefine>

Funktional entspricht dies dem Wert 0 des Attributs minOccurs bei der Gruppenreferenz und erlaubt demnach Inhaltsmodelle ohne ein einziges Auftreten der Basisgruppe. Da dies der Grundabsicht hinter Ableitungen durch Erweiterung widerspricht, sollte diese Art von Struktur nicht verwendet werden. In ähnlicher Weise verbietet die Recommendation nicht die Verwendung eines anderen Kompositors außer xs:sequence beim Redefinieren einer Gruppe. Da jedoch die Verwendung von xs:choice anstelle von xs:sequence zu Gruppen führt, bei denen der Inhalt der Basis weggelassen werden kann, ist dies sicherlich etwas, was vermieden werden sollte.

Die Verweise, die bei der Redefinition zum Erweitern von Gruppen verwendet werden, müssen auf der obersten Ebene der Gruppendefinition stehen. Als letztes sollten wir bei der Erweiterung von Elementgruppen anmerken, daß Selbstreferenzen bei normalen globalen Gruppendefinitionen nicht zum Definieren rekursiver Inhaltsmodelle verwendet werden können, selbst wenn die Redefinitionssyntax eine Gruppenreferenz auf die zu definierende Gruppe enthält. Diese müssen auf niedrigerer Ebene durchgeführt werden, etwa wie folgt:

<xs:group name="group">
   <!-- Diese Gruppendefinition ist *nicht* zulässig -->
   <xs:sequence>
      <xs:element name="foo">
         <xs:complexType>
            <xs:group ref="group" minOccurs="0"/>
         </xs:complexType>
      </xs:element>
      <xs:element name="bar" type="xs:token"/>
   </xs:sequence>
</xs:group>

Einschränkung

Die Redefinition von Attribut- und Elementgruppen durch Einschränkung ähnelt prinzipiell der Ableitung komplexer Typen komplexen Inhalts durch Einschränkung. Eine neue Definition der Gruppe wird angegeben; diese neue Definition muß die gleichen Kriterien wie die einer Einschränkung bei komplexen Typen komplexen Inhalts erfüllen, und sie muß eine gültige Einschränkung der Basisgruppe sein. Inhalt, der zu der redefinierten Gruppe paßt, muß stets auch zu der Basisgruppe passen, und die Elemente, die in der neuen Definition verwendet werden, müssen ausdrückliche Einschränkungen der in der Basisgruppe verwendeten Elemente sein. Nehmen wir diese Gruppendefinition an:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:group name="author">
      <xs:sequence>
         <xs:element ref="name"/>
         <xs:element ref="born"/>
         <xs:element ref="dead" minOccurs="0"/>
         <xs:element name="nationality" type="xs:NMTOKEN" minOccurs="0"/>
      </xs:sequence>
   </xs:group>
</xs:schema>

Wir können diese Gruppe so definieren, daß das optionale Element nationality wegfällt:

<xs:redefine schemaLocation="author.xsd">
   <xs:group name="author">
      <xs:sequence>
         <xs:element ref="name"/>
         <xs:element ref="born"/>
         <xs:element ref="dead" minOccurs="0"/>
      </xs:sequence>
   </xs:group>
</xs:redefine>
<xs:element name="author">
   <xs:complexType>
      Andere Alternativen | 147
      <xs:group ref="author"/>
      <xs:attribute ref="id"/>
   </xs:complexType>
</xs:element>

Bevor wir dieses Thema verlassen, müssen wir noch feststellen, daß die Regeln für die Einschränkung von Attributgruppen sich von den Regeln für die Einschränkung komplexer Typen unterscheiden. Die Liste der Attribute muß alle beizubehaltenden Attribute nennen. (Dies ist anders als bei den Einschränkungen komplexer Typen, bei denen nicht genannte Attribute als unverändert übernommen angesehen werden.) Gehen wir von einer Attributgruppe wie der folgenden aus:

<xs:attributeGroup name="commonAttributes">
   <xs:attribute name="id" type="xs:ID"/>
   <xs:attribute name="available" type="xs:boolean"/>
   <xs:attribute name="lang" type="xs:language"/>
</xs:attributeGroup>
        

Wenn wir sie durch eine Redefinition so einschränken wollen, daß das Attribut available entfernt wird, müssen wir die Definitionen der beiden anderen Attribute wiederholen:

<xs:redefine schemaLocation="attributes.xsd">
   <xs:attributeGroup name="commonAttributes">
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="lang" type="xs:language"/>
   </xs:attributeGroup>
</xs:redefine>

   

<< zurück vor >>

 

 

 

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

Copyright © 2003 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XML Schema" 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.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de