Ein XSD- Beispiel
Dieses Kapitel zeigt, wie man ein XML-Schema schreibt. Sie werden auch lernen, dass ein Schema auf verschiedene Arten geschrieben werden kann.
Ein XML-Dokument
Schauen wir uns dieses XML-Dokument mit dem Namen "shiporder.xml" an:
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
Das obige XML-Dokument besteht aus einem Root-Element, „shiporder“, das ein erforderliches Attribut namens „orderid“ enthält. Das „shiporder“-Element enthält drei verschiedene untergeordnete Elemente: „orderperson“, „shipto“ und „item“. Das Element „item“ erscheint zweimal und enthält einen „title“, ein optionales „note“-Element, ein „quantity“- und ein „price“-Element.
Die obige Zeile: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" teilt dem XML-Parser mit, dass dieses Dokument anhand eines Schemas validiert werden soll. Die Zeile: xsi:noNamespaceSchemaLocation="shiporder.xsd" gibt an, WO sich das Schema befindet (hier im selben Ordner wie "shiporder.xml").
Erstellen Sie ein XML-Schema
Jetzt wollen wir ein Schema für das obige XML-Dokument erstellen.
Wir öffnen zunächst eine neue Datei, die wir "shiporder.xsd" nennen. Um das Schema zu erstellen, könnten wir einfach der Struktur im XML-Dokument folgen und jedes Element so definieren, wie wir es finden. Wir beginnen mit der Standard-XML-Deklaration, gefolgt vom Element xs:schema, das ein Schema definiert:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
Im obigen Schema verwenden wir den Standard-Namespace (xs), und der diesem Namespace zugeordnete URI ist die Schema-Sprachdefinition, die den Standardwert http://www.w3.org/2001/XMLSchema hat.
Als nächstes müssen wir das "shiporder"-Element definieren. Dieses Element hat ein Attribut und enthält andere Elemente, daher betrachten wir es als komplexen Typ. Die untergeordneten Elemente des „shiporder“-Elements sind von einem xs:sequence-Element umgeben, das eine geordnete Folge von Unterelementen definiert:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
Dann müssen wir das Element „orderperson“ als einfachen Typ definieren (weil es keine Attribute oder andere Elemente enthält). Dem Typ (xs:string) wird das Namespace-Präfix vorangestellt, das mit dem XML-Schema verknüpft ist, das einen vordefinierten Schema-Datentyp angibt:
<xs:element name="orderperson" type="xs:string"/>
Als nächstes müssen wir zwei Elemente des komplexen Typs definieren: „shipto“ und „item“. Wir beginnen mit der Definition des "shipto"-Elements:
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Mit Schemas können wir die Anzahl der möglichen Vorkommen für ein Element mit den Attributen maxOccurs und minOccurs definieren. maxOccurs gibt die maximale Anzahl von Vorkommen für ein Element an und minOccurs gibt die minimale Anzahl von Vorkommen für ein Element an. Der Standardwert für maxOccurs und minOccurs ist 1!
Jetzt können wir das Element „item“ definieren. Dieses Element kann mehrmals innerhalb eines "shiporder"-Elements erscheinen. Dies wird angegeben, indem das Attribut maxOccurs des Elements „item“ auf „unbounded“ gesetzt wird, was bedeutet, dass es so viele Vorkommen des Elements „item“ geben kann, wie der Autor es wünscht. Beachten Sie, dass das Element „note“ optional ist. Wir haben dies angegeben, indem wir das Attribut minOccurs auf Null gesetzt haben:
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Wir können jetzt das Attribut des Elements "shiporder" deklarieren. Da dies ein erforderliches Attribut ist, geben wir use="required" an.
Hinweis: Die Attributdeklarationen müssen immer zuletzt kommen:
<xs:attribute name="orderid" type="xs:string" use="required"/>
Hier ist die vollständige Auflistung der Schemadatei mit dem Namen "shiporder.xsd":
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
Teilen Sie das Schema
Die vorherige Entwurfsmethode ist sehr einfach, kann jedoch schwierig zu lesen und zu verwalten sein, wenn Dokumente komplex sind.
Die nächste Entwurfsmethode basiert darauf, zuerst alle Elemente und Attribute zu definieren und dann mit dem Attribut ref auf sie zu verweisen.
Hier ist das neue Design der Schemadatei ("shiporder.xsd"):
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
Benannte Typen verwenden
Die dritte Entwurfsmethode definiert Klassen oder Typen, die es uns ermöglichen, Elementdefinitionen wiederzuverwenden. Dazu benennen Sie die simpleTypes- und complexTypes-Elemente und zeigen dann über das type-Attribut des Elements darauf.
Hier ist das dritte Design der Schemadatei ("shiporder.xsd"):
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>
Das Einschränkungselement gibt an, dass der Datentyp von einem W3C-XML-Schema-Namespace-Datentyp abgeleitet ist. Das folgende Fragment bedeutet also, dass der Wert des Elements oder Attributs ein Zeichenfolgenwert sein muss:
<xs:restriction base="xs:string">
Das Beschränkungselement wird häufiger verwendet, um Beschränkungen auf Elemente anzuwenden. Sehen Sie sich die folgenden Zeilen aus dem obigen Schema an:
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
Dies zeigt an, dass der Wert des Elements oder Attributs eine Zeichenfolge sein muss, es muss genau sechs Zeichen in einer Reihe sein, und diese Zeichen müssen eine Zahl von 0 bis 9 sein.