14.3 Die Gültigkeit eines XML-Dokuments
Der XML-Standard definiert selbst keine Elemente (Tags), sondern beschreibt nur die Wohlgeformtheit. Für den Datenaustausch zwischen Anwendungen oder Systemen ist das meist nicht ausreichend, denn dazu bedarf es zusätzlich eines festen Musters, wie die Elemente im XML-Dokument strukturiert werden. Wird ein XML-Dokument zwischen zwei Anwendungen ausgetauscht, müssen sich beide Anwendungen in dieser Hinsicht an dieselben Vorgaben halten, um die korrekte Interpretation der Daten zu gewährleisten.
In der Datenverarbeitung ist ein Schema ein allgemein gültiger Begriff für eine Beschreibung einer Menge von Daten. Im Kontext von XML ist ein Schema die Beschreibung eines XML-Dokuments. Mit Hilfe eines Schemas wird die Gültigkeit von XML-Dokumenten überprüft. Ein XML-Dokument, das die im Schema definierten Regeln einhält, gilt als wohlgeformt und gültig. Ein solches Dokument kann von jeder Anwendung in Verbindung mit dem Schema richtig verarbeitet werden.
Ein Schema wird speziell für ein ganz bestimmtes XML-Dokument bereitgestellt und kann auf zweierlei Art mit einem Dokument verknüpft werden:
- Das Schema ist selbst Bestandteil des XML-Dokuments.
- Das Schema wird als separate Datei bereitgestellt.
Es gibt drei wesentliche Schemata zur Beschreibung der Gültigkeit: Document Type Definition (DTD), XML Schema Definition (XSD) und XDR (XML Data Reduced). In den vergangenen Jahren hat sich XSD zu einem Quasistandard entwickelt. Das liegt sicher nicht nur daran, dass XSD mehr Möglichkeiten bietet als DTD, sondern darüber hinaus kann ein XSD-Schema mittels passender Tools schneller bereitgestellt werden als eine auf DTD basierende Dokumenttyp-Definition. XDR ist eine Schemadefinition aus dem Haus Microsoft, die aber von Microsoft selbst nicht mehr unterstützt wird. Aus den genannten Gründen werden wird uns an dieser Stelle ausschließlich mit XSD beschäftigen.
14.3.1 XML Schema Definition (XSD)

XSD (XML Schema Definition) ist seit 2001 eine Empfehlung des W3-Konsortiums, um den Inhalt und die Struktur eines XML-Dokuments zu beschreiben. XML-Schemata basieren ihrerseits selbst auf XML. Nach dem aktuellen Stand stehen Ihnen insgesamt 44 vordefinierte Datentypen zur Verfügung, z. B. int, short, float oder date. Zudem lassen sich aber auch benutzerdefinierte Typen und die Reihenfolge des Auftretens der Elemente beschreiben.
Betrachten wir exemplarisch die folgende XML-Datei Personen.xml:
<?xml version="1.0" encoding="utf-8"?>
<Personen>
<Person>
<Name>Walter Meier</Name>
<Wohnort>Frankfurt</Wohnort>
</Person>
</Personen>
Listing 14.11 XML-Dokument
Die Schemadatei Personen.xsd, die die Struktur dieses XML-Dokuments beschreibt, lautet wie folgt:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Personen" xmlns=""
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Personen" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Wohnort" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Listing 14.12 Schemadatei des XML-Dokuments aus Listing 14.11
Das Tool xsd.exe
Ein neues XML-Dokument zu erstellen stellt keine große Hürde dar, wenn die Regeln der Wohlgeformtheit beachtet werden. Ganz anders sieht es aus, wenn Sie ein XML-Schema bereitstellen möchten, mit dessen Hilfe Sie ein bestimmtes XML-Dokument validieren wollen. Dazu sind viele spezifische Kenntnisse erforderlich, um am Ende das erforderliche Ergebnis zu erreichen. Erfreulicherweise wird uns aber die Arbeit von dem Kommandozeilentool xsd.exe abgenommen, das zusammen mit Visual Studio 2012 geliefert wird.
Sie können das Tool auf vielfältige Weise einsetzen. Wenn Sie eine XML-Datei angeben (Erweiterung .xml), leitet xsd.exe ein Schema aus den Daten in der Datei ab und erstellt ein XSD-Schema. Die Ausgabedatei erhält den Namen der XML-Datei mit der Erweiterung .xsd, z. B.:
xsd.exe Personen.xml
Mit dieser Anweisung wird zu der XML-Datei Personen.xml ein passendes XML-Schema namens Personen.xsd erzeugt. Obwohl Ihnen xsd.exe eigentlich die meiste Arbeit abnimmt, sollten Sie dennoch die wesentlichsten Elemente eines XML-Schemas verstehen, denn möglicherweise sind weitere Anpassungen nötig. Dem Verständnis des Inhalts eines XML-Schemas wollen wir uns nun widmen.
14.3.2 Ein XML-Dokument mit einem XML-Schema verknüpfen

Um ein XML-Dokument mit einem externen XML-Schema zu verbinden, müssen Sie im Stammelement des XML-Dokuments den Namespace
angeben. Üblicherweise wird dabei das Präfix xsi verwendet. Anschließend wird die mit dem XML-Dokument zu verknüpfende Schemadatei festgelegt. Dazu bieten sich mit den Attributen
- noNamespaceSchemaLocation und
- schemaLocation
zwei Möglichkeiten. Ausgangspunkt der nachfolgenden Betrachtungen sei erneut das XML-Dokument Personen.xml aus Listing 14.11.
Das Attribut »noNamespaceSchemaLocation«
Das Attribut noNamespaceSchemaLocation verwenden Sie, wenn den im XSD-Dokument beschriebenen Elementen kein spezifischer Namespace zugeordnet werden soll. Das ist in unserem Beispieldokument der Fall. Wir können das XML-Dokument mit einer Schemadatei verknüpfen, indem wir das Attribut noNamespaceSchemaLocation verwenden und die Schemadatei angeben.
<Personen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Personen.xsd">
Als Wert verwenden Sie die absolute oder relative Pfadangabe der Schemadatei.
Die Validierung lässt sich recht gut mit XML-Notepad 2007 prüfen. Öffnen Sie das Tool, und laden Sie die XML-Datei in den Editor. Es wird kein Fehler angezeigt.
Sie können nun die Auswirkung eines Validierungsfehlers testen und müssen dazu zuerst eine Änderung in der XSD-Datei vornehmen. Dazu öffnen Sie die Schemadatei und ändern das Attribut minOccurs des Elements Name vom Wert »0« in »1« ab.
<xs:element name="Name" type="xs:string" minOccurs="1" />
Damit legen Sie fest, dass das Element Name in jedem Fall angegeben werden muss. Speichern Sie die Schemadatei, und öffnen Sie Personen.xml.
Im nächsten Schritt löschen Sie das <Name>-Element in der XML-Datei, speichern diese und öffnen sie erneut in XML-Notepad. Da das XML-Dokument nicht mehr den Vorgaben in der Schemadatei entspricht, wird sofort ein Validierungsfehler angezeigt (siehe Abbildung 14.4).
Abbildung 14.4 Anzeige eines Validierungsfehlers in XML-Notepad 2007
Anstatt des hier beschriebenen Attributs noNamespaceSchemaLocation können Sie auch das im folgenden Abschnitt gezeigte Attribut schemaLocation verwenden.
Das Attribut »schemaLocation«
Das Attribut schemaLocation findet Verwendung, wenn die in einer Schemadatei beschriebenen Elemente im XML-Dokument mit einem spezifischen Namespace in Beziehung gesetzt werden sollen. Angenommen, wir würden für das Element <Person> einen Namespace wie folgt festlegen:
<?xml version="1.0" encoding="utf-8"?>
<Personen xmlns:pers=http://www.tollsoft.de
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation="http://www.tollsoft.de Personen.xsd">
<pers:Person>
<Name>Walter</Name>
<Wohnort>Frankfurt</Wohnort>
</pers:Person>
</Personen>
Listing 14.13 Angabe von »schemaLocation« im XML-Dokument
Es wird im XML-Dokument auf die Schemadatei Personen.xsd verwiesen. Alle dort beschriebenen Elemente werden dem Namespace http://www.tollsoft.de zugeordnet, für den im XML-Dokument das Präfix pers gesetzt ist.
In der Praxis werden nicht selten mehrere unterschiedliche XML-Dokumente zusammengeführt, um daraus ein Dokument zu formen, in dem alle Daten der Einzeldokumente enthalten sind. Auch hierzu eignet sich das Attribut schemaLocation. Die einzelnen XML-Schemata werden unter Angabe des jeweils zugeordneten spezifischen Namespaces der Reihe nach im Attribut aufgelistet. Auch dazu ein Beispiel.
<?xml version="1.0"?>
<p:Person
xmlns:p="http://NS1"
xmlns:a="http://NS2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://NS1 Person.xsd
http://NS2 Auto.xsd">
<Name>John</Name>
<Alter>45</Alter>
<a:Auto>
<Farbe>rot</Farbe>
<Sitze>4</Sitze>
</a:Auto>
</p:Person>
Listing 14.14 Mehrere »schemaLocation«-Angaben in einem XML-Dokument
Das gezeigte XML-Dokument führt die in zwei separaten XML-Dokumenten enthaltenen Daten zusammen. Das erste Dokument beschreibt das Person-Element, das zweite das Auto-Element. Das Gesamtdokument soll dem Zweck dienen, einer Person ein bestimmtes Auto zuzuordnen. Die Schemainformationen stammen aus den Schemadateien Person.xsd und Auto.xsd. Im Attribut schemaLocation wird Person.xsd mit dem Namespace NS1 in Beziehung gesetzt, Auto.xsd mit dem Namespace NS2. Darüber hinaus werden mit
xmlns:p="http://NS1"
xmlns:a="http://NS2"
beide Namespaces durch Präfixe beschrieben. Die beiden Elemente Person und Auto im XML-Dokument können nun aufgrund der Präfixangabe eindeutig einem XML-Schema zugeordnet werden.
Weiter unten in diesem Kapitel wird noch das Attribut targetNamespace eines XML-Schemas erläutert. In diesem Zusammenhang werden Sie auch noch weitere Informationen hinsichtlich der hier vorgestellten Attribute noNamespaceSchemaLocation und schemaLocation erhalten.
14.3.3 Die Struktur eines XML-Schemas

Die Grundstruktur
Das folgende Beispiel zeigt Ihnen einige grundlegende Elemente in einer einfachen Struktur. Darin sind Elemente enthalten, die in fast jedem XML-Schema auftreten können.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" ... >
<xs:element name="Stammelement">
<xs:complexType>
<xs:sequence>
<xs:element name="Unterelement1"/>
<xs:element name="Unterelement2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Listing 14.15 Die Grundstruktur eines XML-Schemas
Das Element schema bildet das Wurzelelement eines XML-Schemas. Es beschreibt eine Reihe von Namespaces. Der wichtigste ist in dem Beispiel angegeben, nämlich http://www.w3.org/2001/XMLSchema, der üblicherweise durch das Präfix xs beschrieben wird. Diesem Namespace sind alle vordefinierten Elemente des XML-Schemas zugeordnet.
Einfache Elemente
Ein Element, das selbst keine Attribute und untergeordneten Elemente enthalten kann, wird als einfaches Element bezeichnet. Es beschreibt ein Tag in einem XML-Dokument. Einfache Elemente werden über xs:element definiert. Der Bezeichner wird über das Attribut name festgelegt, der Datentyp über type.
<xs:element name="Elementname" type="xs:Datentyp" />
Mit dem zusätzlichen Attribut default können Sie einen Standardwert bestimmen, mit fixed einen festen Wert.
Attribute
Ein einfaches Element, wie es im Abschnitt zuvor beschrieben worden ist, kann keine Attribute haben. Ein Element mit Attributen im XML-Dokument muss als komplexes Element definiert sein (siehe dazu auch den folgenden Abschnitt). Innerhalb eines komplexen Elements wird ein Attribut ähnlich einem einfachen Element beschrieben.
<xs:attribute name ="Attributname" type="xs:Datentyp" />
Darüber hinaus lassen sich auch die zusätzlichen Attribute default und fixed angeben, die dieselbe Bedeutung haben wie bei den einfachen Elementen.
Interessant ist noch ein weiteres mögliches Attribut: use. Mit diesem lässt sich festlegen, ob das Attribut im XML-Dokument angegeben werden muss. Die möglichen Werte für use sind required (zwingend erforderlich), optional (wahlweise) und prohibited (verboten). Wird use nicht angegeben, gilt ein Attribut als optional. Beispiel:
<xs:attribute name ="Attributname" type="xs:Datentyp" use="required" />
Eine besondere Bedeutung kommt der Positionsangabe der Attribute im XML-Schema zu, denn die Definition von Attributen darf nur am Ende eines komplexen Elements, direkt vor dem schließenden Tag </xs:element> erfolgen.
Soll zum Beispiel das Element
<Adresse Ort="Bonn" Strasse="Neuestr.34"></Adresse>
in einem XML-Schema beschrieben werden, müsste die entsprechende Passage wie folgt lauten:
<xs:element name="Adresse" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Ort" type="xs:string" />
<xs:attribute name="Strasse" type="xs:string" />
</xs:complexType>
</xs:element>
Komplexe Elemente
Komplexe Elemente in einem XML-Schema beschreiben XML-Dokument-Elemente, die Attribute oder weitere, untergeordnete Elemente aufweisen. Betrachten Sie als Beispiel den folgenden Ausschnitt aus einer XML-Datei:
<Person>
<Vorname>Manfred</Vorname>
<Telefon/>
<Zuname>Fischer</Zuname>
</Person>
Listing 14.16 Ausschnitt aus einem XML-Dokument
Das Element Person wird beschrieben durch die untergeordneten Elemente Vorname, Zuname und Telefon. Dieser Ausschnitt könnte in einem XML-Schema folgendermaßen definiert werden:
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="Vorname" type="xs:string" minOccurs="0" />
<xs:element name="Telefon" type="xs:string" minOccurs="0" />
<xs:element name="Zuname" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
Listing 14.17 Schemadefinition des XML-Ausschnitts aus Listing 14.16
Wie zu erkennen ist, wird das Element Person mit <complexType> als komplexes Element angelegt. Das Element <sequence> legt fest, dass die nachfolgenden Elemente in der angegebenen Reihenfolge im XML-Dokument erscheinen müssen, also zuerst Vorname, dann Telefon und zum Schluss Zuname.
Dürfen die Unterelemente in einer beliebigen Reihenfolge im XML-Dokument auftreten, dann wird die Liste dieser Elemente anstatt mit <sequence> mit <all> beschrieben.
<xs:element name="Person">
<xs:complexType>
<xs:all>
<xs:element name="Vorname" type="xs:string" minOccurs="0" />
<xs:element name="Telefon" type="xs:string" minOccurs="0" />
<xs:element name="Zuname" type="xs:string" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:element>
Listing 14.18 Schema einer komplexen Datenstruktur
Es gibt mit <choice> noch eine dritte Variante, komplexe Elemente zu beschreiben. Damit lässt sich eine Auswahl von Elementen festlegen. In einem XML-Dokument darf allerdings nur eines der angegebenen Elemente auftreten. Im folgenden Codefragment muss entweder Mann oder Frau als Element von Person erscheinen.
<xs:element name="Person">
<xs:complexType>
<xs:choice>
<xs:element name="Mann" type="xs:string" />
<xs:element name="Frau" type="xs:string" />
</xs:choice>
</xs:complexType>
</xs:element>
Listing 14.19 »choice« zur Beschreibung einer Auswahlmöglichkeit
minOccurs und maxOccurs
Die Attribute minOccurs und maxOccurs werden nur in komplexen Typdefinitionen angezeigt. Damit wird einschränkend festgelegt, wie oft in Folge das entsprechende Element in der entsprechenden Position in einem XML-Dokument angezeigt werden kann.
<xs:element name="Telefon" type="xs:string"
minOccurs="0" maxOccurs="unbounded" />
Die Werte dieser beiden Attribute sind immer positive Zahlen. maxOccurs kann auch auf unbounded gesetzt werden, so dass eine unbegrenzte Anzahl von Elementen auftreten kann. Für sequence, all und choice sind die Werte von minOccurs und maxOccurs standardmäßig immer 1.
Die Attribute »elementFormDefault« und »attributeFormDefault«
Das Attribut elementFormDefault="qualified" erzwingt, dass alle untergeordneten Elemente im XML-Dokument demselben Namespace wie das globale Element zugeordnet sind. Betrachten Sie dazu das folgende Fragment eines XML-Schemas:
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="TestURN"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Listing 14.20 Die Attribute »elementFormDefault« und »attributeFormDefault«
Das folgende Dokument ist gültig, denn alle Elemente sind zweifelsfrei dem Standard-Namespace zuzuordnen, der durch TestURN beschrieben wird.
<!--Dokument valide -->
<Personen xmlns="TestURN"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="TestURN Personen.xsd">
<Person>
<Zuname>Fischer</Zuname>
<Adresse Ort="Bonn"></Adresse>
</Person>
</Personen>
Das folgende XML-Dokument ist allerdings ungültig, da Personen das Präfix »x« vorangestellt ist. Damit wird Personen durch den Namespace TestURN qualifiziert, während alle anderen Elemente keinem spezifischen Namespace angehören.
<!--Dokument nicht valide -->
<x:Personen xmlns:x="TestURN"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="TestURN Personen.xsd">
<Person>
<Zuname>Fischer</Zuname>
<Adresse Ort="Bonn"></Adresse>
</Person>
</x:Personen>
In diesem Fall müssten auch die Elemente Person, Zuname und Adresse mit dem Präfix x qualifiziert werden, damit das Dokument wieder gültig ist.
Die Einstellung elementFormDefault="unqualified" schreibt den lokalen Elementen im XML-Dokument vor, dass sie keine qualifizierende Namespace-Angabe haben dürfen. Sehen wir uns auch dazu ein Beispiel an.
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="TestURN"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Listing 14.21 Das Attribut »elementFormDefault«
Die Validierung des folgenden XML-Dokuments schlägt fehl, denn das Element Person gehört zu dem durch den Standard-Namespace beschriebenen Namespace TestURN.
<!-- Dokument nicht valide -->
<Personen xmlns="TestURN"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="TestURN Personen.xsd">
<Person>
<Zuname>Fischer</Zuname>
<Adresse Ort="Bonn"></Adresse>
</Person>
</Personen>
Listing 14.22 Nicht valides XML-Dokument
Damit das XML-Dokument gültig ist, muss das Stammelement Personen über ein Präfix dem spezifischen Namespace TestURN zugeordnet werden, und das lokale Element Person darf nicht qualifiziert werden.
<!-- Dokument valide -->
<x:Personen xmlns:x="TestURN"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="TestURN Personen.xsd">
<Person>
<Zuname>Fischer</Zuname>
<Adresse Ort="Bonn"></Adresse>
</Person>
</x:Personen>
Das attributeFormDefault-Attribut behält am besten seinen Standardwert unqualified, nicht qualifiziert, da die meisten Schemaautoren nicht alle Attribute ausdrücklich durch Präfixe mit Namespaces qualifizieren möchten.
Das Attribut »targetNamespace«
Das Attribut targetNamespace (Zielnamensraum) legt im XML-Schema fest, welchem Namespace alle beschriebenen Elemente angehören. Im folgenden Ausschnitt ist der Zielnamensraum TestURN.
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="TestURN"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Listing 14.23 Festlegen des Zielnamensraums
Ist im XML-Schema das Attribut targetNamespace festgelegt, müssen Sie das im XML-Dokument berücksichtigen, indem Sie dort die Verknüpfung zwischen dem XML-Dokument und dem XML-Schema über das Attribut schemaLocation definieren. schemaLocation setzt sich aus zwei Einträgen zusammen: Im ersten beschreibt man den im XML-Schema festgelegten Zielnamensraum, im zweiten den absoluten oder relativen Pfad zur XSD-Datei.
<Personen xmlns="TestURN"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="TestURN Personen.xsd">
Sie müssen vorsichtig sein, wenn Sie den Elementen im XML-Dokument einen Namespace zuordnen. Im letzten XML-Fragment ist mit
xmlns="TestURN"
der Standard-Namespace auf den im XML-Schema angegebenen Zielnamensraum festgelegt. Somit können alle Elemente anhand des Schemas validiert werden. Benutzen Sie eine andere Namensraumangabe, beispielsweise
xmlns="urn:Personen-schema"
werden alle Elemente im XML-Dokument einem anderen Namespace zugeordnet und können nicht mehr gegen die Schemadatei validiert werden.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.