XML Schema - Computer Web2013.de
Transcrição
XML Schema - Computer Web2013.de
XML-Schema 175 5 XML-Schema Im vorhergehenden Kapitel haben Sie sich mit benutzerspezifischen XMLDokumenten befasst, deren Struktur über DTDs definiert wurde. Das aktuelle Kapitel befasst sich mit der Frage, wie sich Dokumenttypen über Schemata definieren lassen. 5.1 Einführung in XML-Schema XML-Schema stellt einen neuen Ansatz dar, um XML-Dokumenttypen unter Verzicht auf DTDs zu vereinbaren. In diesem Abschnitt wird kurz diskutiert, warum dieser Ansatz gewählt wurde und wie ein einfaches Beispiel aussieht. Außerdem stelle ich Ihnen kurz zwei Windows-Werkzeuge vor, die den Entwurf und den Einsatz solcher XML-Schemata unterstützen. 5.1.1 Warum ein Schema statt einer DTD verwenden? In der XML-Spezifikation 1.0 wird die Document Type Definition (DTD) benutzt, um Dokumenttypen zu definieren. Dieser Aspekt wurde in Kapitel 4 recht ausführlich erklärt. Nachdem Sie mit DTDs umgehen können, stellt sich die Frage, warum ein neuer Ansatz zur Definition der Dokumenttypen benutzt wird und was es damit auf sich hat? Nun, bei der Verwendung von DTDs zur Definition von Dokumenttypen tauchen mehrere Probleme auf: • Einmal ist es natürlich recht ungeschickt, wenn zur Definition des Dokumenttyps eine andere Notation als zur Erstellung des Dokuments benutzt wird. Warum kann die Definition nicht mit XML-Elementen erfolgen? • Die DTD sieht für XML-Elemente nur vier rudimentäre Datentypen vor, wobei fast alles darauf hinausläuft, dass ein Element Zeichenketten aufnimmt, die Unterelemente oder Daten darstellen. Der Versuch, die Werte eines Elements auf Zahlen, Integerwerte etc. zu beschränken, ist damit zum Scheitern verurteilt. Weiterhin lässt sich die DTD nicht erweitern, da der Umfang der möglichen Schlüsselwörter etc. in der XML-Spezifikation 1.0 fest vorgeschrieben ist. Validieren Sie ein auf einer DTD basierendes XMLDokument, gibt es keine Möglichkeit, nicht deklarierte Elemente zu verwenden. Sie müssen entweder auf eine Validierung verzichten oder die © Günter Born - www.borncity.de ICON: Hin 176 Einführung in XML-Schema DTD erweitern. Bei XML-Schema haben Sie die Möglichkeit, zusätzlich zum validierbaren Dokumentinhalt neue Elemente oder Attribute einzufügen. Aus diesem Grund begannen Firmen, die sich mit praktischen Anwendungen von XML befassten, sich bereits frühzeitig unter Federführung von Microsoft nach Alternativen umzusehen. Es kristallisierte sich recht schnell heraus, dass eine Dokumentstruktur eigentlich direkt durch XML-Elemente beschreibbar sein sollte. Nehmen wir einmal einen einfachen XML-Dokumenttyp, der folgende Struktur besitzt: <daten> <person> <name>...</name> <vorname>...</vorname> <tel>...</tel> </person> </daten> Eine DTD für diese Struktur sähe dann folgendermaßen aus: <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT daten person name vorname tel (person)+> (name, vorname, tel)> (#PCDATA)> (#PCDATA)> (#PCDATA)> Auch wenn diese DTD nicht sonderlich kompliziert ist, erfordert die Anwendung der Syntaxregeln schon etwas Erfahrung. Andererseits haben wir mit der obigen Definition der XML-Elementstruktur doch so etwas wie eine Schablone, auch als Schema bezeichnet, die in etwa die Struktur des Dokumenttyps beschreibt. Würde dieser Ansatz weiterentwickelt, ließe sich die Struktur des XML-Dokumenttyps doch einfach mit XML-Elementen beschreiben. Und genau hier setzt ein XML-Schema an. Sie könnten doch die Struktur auch folgendermaßen umschreiben: <xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"> <xsd:annotation><!-- Anmerkungen als Kommentar --> <xsd:documentation> Definition eines Person-Schemas </xsd:documentation> </xsd:annotation> <!-- Definition der Elemente --> <xsd:complexType name="daten"> <xsd:complexType name="person"/> <element name="name" type="string" /> <element name="vorname" type="string" /> <element name="tel" type="string" /> </xsd:xsd:complexType> </xsd:xsd:complexType> </xsd:schema> © Günter Born - www.borncity.de XML-Schema 177 Das Wurzelelement schema definiert über das Attribut xmlns eine Referenz auf den Namensraum, in dem die zulässigen Elemente für die Schemadatei festgelegt sind (hier wird ein Namensraum des W3C für XML-Schema angegeben). Das Wurzelelement enthält weitere Element, die die Struktur des XML-Dokuments beschreiben. Das Element annotation dient hier lediglich zur Aufnahme eines Kommentars, der Hinweise zur Struktur liefert. Interessanter ist das erste complexType-Element, welches über das name-Attribut ein Element mit dem Namen daten definiert. Ein weiteres complexType-Unterelement legt anschließend das Element person fest. Dieses Element enthält weitere element-Einträge, die die eigentlichen Dokumentelemente beschreiben. Auch wenn bei obigem Schema noch Angaben bezüglich Wiederholungen von Elementen etc. fehlen, ist die Struktur des XML-Dokuments ersichtlich. Und Sie sehen, dass für die Elemente weitere Datentypen (wie z.B. string) verfügbar sind. Ein XML-Schema spezifiziert also die Struktur einer XML-Dokumentklasse und enthält Hinweise auf die zulässigen Elemente bzw. Attribute. XML-Schema in der Praxis XML-Schema stellt eigentlich einen sehr interessanten Ansatz zur Beschreibung von Dokumentklassen dar. Das W3C hat diesen Ansatz zwar aufgegriffen, es liegen zurzeit aber nur Working Drafts vor. Diese Entwürfe für XML-Schema können Sie über die Webseiten des W3C (www.w3c.org) abrufen. Die obigen Ausführungen wurden verfasst, als die W3CSpezifikation für XML-Schema erst als Arbeitsentwurf (Working Draft, 22. September 2000) vorlagen. Von Microsoft wurden Teile von XML-Schema bereits frühzeitig in eigenen Produkten implementiert. Die Implementierung im Microsoft XML-Parser MSXML (Version 2.0 bis 3.0) basiert dabei auf den Konzepten, die in folgenden Dokumenten hinterlegt sind: XML Data Reduced (http://www.w3.org/TR/1998/NOTE-XML-data-0105, Januar 1998) und Document Content Description (DCD) (http://www.w3.org/TR/NOTE-dcd). Die Implementierung verzichtet auf Vererbung und einige objektorientierte Ansätze dieser Dokumente und konzentriert sich auf Funktionen, die zum Ersetzen einer DTD benötigt werden. Die Implementierung im Microsoft XML-Parser des Internet Explorer 5.0 wird daher als XDR-Schema bezeichnet und weicht geringfügig von den W3C-Arbeitsentwürfen ab. Die nachfolgenden Ausführungen zu XDR-Schema beziehen sich daher konkret auf die Vorgaben des Microsoft XML-Parsers. © Günter Born - www.borncity.de 178 Einführung in XML-Schema Auch andere Werkzeuge wie XML Spy oder XMLwriter unterstützen wie der Microsoft XML-Parser bereits XML-Schema als Untermenge von XMLData. 5.1.2 Ein Beispiel für ein XML-Schema (Microsoft) Der folgende Quellcode bildet das Schema für den Beispiel-Dokumenttyp (in der bei Microsoft für den XML-Parser benutzten Notation) ab. <?xml version='1.0' encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata" xmlns:dt="urn:schemas-microsoft-com:datatypes"> <!-Schema für Personendaten (basiert auf dem XML-Schema-Support des Microsoft Internet Explorer 5) --> <!-- Child-Elemente deklarieren --> <ElementType name="vorname" content="textOnly"/> <ElementType name="name" content="textOnly"/> <ElementType name="tel" dt:type="string"/> <!-- Jetzt kommt das Element für Personen --> <ElementType name="person" content="eltOnly"> <element type="vorname"/> <element type="name"/> <element type="tel"/> </ElementType> <!-- Und nun das Wurzelelement --> <ElementType name="daten" content="eltOnly"> <element type="person"/> </ElementType> </Schema> Der Quellcode beginnt wie andere XML-Dokumente ebenfalls mit einer XML-Deklaration. Statt der DOCTYPE-Deklaration folgt jedoch ein Schema-Element, welches Unterelemente mit den Definitionen für den Dokumenttyp enthält. Ohne jetzt allzu sehr auf die Details einzugehen, es ist sicherlich schnell ersichtlich, dass die Elemente des Dokumenttyps über ElementType-Elemente beschrieben werden. Zusätzlich haben Sie die Möglichkeit, die Anordnung der Elemente durch das element-Element festzulegen (auf die Details gehe ich später noch ein). © Günter Born - www.borncity.de ICON: Bei XML-Schema 179 Im Wurzelelement der Schemadatei werden dabei Verweise auf die Namensräume xml-data und datatypes vereinbart. In diesen Namensräumen sind die Elemente und Attribute, die in der Schemadatei benutzt werden dürfen, vereinbart. Datentypen sind dabei über das Präfix dt festzulegen. Die Definition kann mit jedem Texteditor bzw. XML-Editor erstellt und als XML-Datei gespeichert werden. Gemäß den W3C-Vorschlägen wird die Dateinamenerweiterung .xsd benutzt (das Kürzel xsd steht dabei für XML Schema Definition). Von Microsoft verfasste Beispiele nutzen aber auch die Dateinamenweiterung .xml. 5.1.3 Einbinden des Schemas im XML-Dokument Sobald Sie eine Schemadatei vorliegen haben, muss diese (ähnlich wie eine DTD) im XML-Dokument referenziert werden. Die XML-Datei mit einem Datensatz könnte beispielsweise folgendermaßen aussehen: <?xml version='1.0' encoding="ISO-8859-1"?> <daten xmlns="x-schema:Schema.xml"> <person> <vorname>Klaus</vorname> <name>Berninger</name> <tel>089-333-4145</tel> </person> </daten> ICON: Bei Die XML-Dokumentdatei gleicht dem Aufbau, der in den vorangegangenen Kapiteln benutzt wurde. Die einzige Abweichung tritt in der zweiten Zeile auf. Dort finden Sie das daten-Element, welches das Attribut xmlns benutzt, um die Referenz auf die Schemadatei zu vereinbaren. An dieser Stelle wird auf ein Präfix für den Namensraum verzichtet. Dies erspart Ihnen die betreffenden Angaben bei allen Elementen. Eine solche Vereinfachung ist hier zulässig, da wir nur einen Namensraum verwenden. Der Wert des Attributs wird auf "x-schema:Schema.xml" gesetzt. Der Ausdruck x-schema: signalisiert dem XML-Parser, dass die Definition des Dokumenttyps in einer Schemadatei hinterlegt ist. Die Schemadatei wird durch einen Doppelpunkt getrennt als URL angeben. Im obigen Beispiel wird eine relative Pfadangabe benutzt, daher muss die Datei im gleichen Verzeichnis wie das XML-Dokument vorliegen. Im Beispiel wurde Schema.xml gewählt, die Datei hätte aber auch Schema.xsd genannt werden können. Der Attributwert signalisiert dem XML-Parser also, dass er das XML-Dokument gegenüber der angegebenen Schemadatei validieren kann. © Günter Born - www.borncity.de ICON: Hin 180 Einführung in XML-Schema Abbildung 5.1: Darstellung eines auf XML-Schema basierenden XMLElements Das Element daten enthält dann in bekannter Weise die Daten eines Benutzers. Gegenüber den bisherigen Ausführungen hat sich an dieser Stelle nichts geändert. Sie können die Beispieldatei im Internet Explorer laden, validieren und anzeigen lassen (Abbildung 5.1). Sie können das Beispiel an den Dateien im Ordner \Beisp\Kap05 der Begleit-CD verifizieren. Die Datei Bsp05_01.xml bezieht sich auf die Schemadatei Schema.xml und stellt ein gültiges XML-Dokument dar. Die zweite Schemadatei Schema1.xsd entspricht vom Inhalt der Datei Schema.xml. Diese Schemadatei wird im XML-Dokument Bsp05_01a.xml referenziert. Die XML-Dokumentdatei enthält zusätzlich das undefinierte Element fax. Validieren Sie diese Beispieldatei, muss diese als ungültig abgewiesen werden. 5.1.4 XML-Schema: Werkzeuge Zur Anzeige eines auf einem Schema basierenden Dokuments lässt sich der Microsoft Internet Explorer ab der Version 5.0 verwenden. Der XML-Parser dieses Programms unterstützt das in diesem Kapitel benutzte XDRSchemaformat (welches geringfügig vom W3C-Entwurf abweicht). Um Schemadateien zu erstellen, können Sie jeden beliebigen Editor verwenden. Optimaler ist es jedoch, einen XML-Editor zum Erstellen der © Günter Born - www.borncity.de ICON: Hin XML-Schema 181 Schemadatei zu benutzen. Der XML-Editor XMLwriter unterstützt dies durch eine eigene Vorlagedatei, die die Grundstruktur der Schemadatei gemäß der Microsoft-Notation enthält. Das Ergebnis wird dann in einer .xsdDatei gespeichert. Abbildung 5.2: XMLwriter mit Schemadefinition (rechts) und geladenem Schema als TagBar (linkes Fenster) Eine solche Schemadatei können Sie anschließend im XMLwriter als so genannte TagBar laden (Abbildung 5.2, linkes Fenster). Anschließend lässt sich im rechten Fenster ein XML-Dokument basierend auf diesem Schema erstellen. Hierzu ziehen Sie ein Element aus der TagBar (linkes Fenster) in den Dokumentbereich des rechten Fensters. Oder Sie klicken mit der rechten Maustaste auf die Schemadefinition und wählen im Kontextmenü den gewünschten Befehl. Der bereits in Kapitel 4 vorgestellte XML-Editor XML Spy unterstützt XMLSchema ebenfalls. Die Schemadatei können Sie manuell wie andere (DTDlose) XML-Dokumente entwerfen. Wenn Sie anschließend ein neues XMLDokument anlegen und das Schema angeben, erlaubt der Editor die im Schema definierten Elemente im Dokument zu verwenden. Weiterhin kann der Editor das XML-Dokument gegenüber dem Schema validieren (wobei auf die Funktionen des Internet Explorer 5.0 zugegriffen wird). © Günter Born - www.borncity.de 182 Arbeiten mit XML-Schema (XDR) 5.2 Arbeiten mit XML-Schema (XDR) Der folgende Abschnitt enthält eine Einführung in den Entwurf von XDRLSchemata. Dabei stützen sich die Beispiele auf die Notation, die vom Microsoft XML-Parser des Internet Explorer 5.0 unter dem Begriff XDRSchema benutzt wird. Die Benennung der in einer XDR-Schemadatei nutzbaren Elemente und deren Attribute sind auf die Verwendung im XML-Parser (MSXML 2.0 bis 3.0) von Microsoft abgestimmt. Eine später veröffentlichte W3C-Spezifikation zu XML-Schema wird wohl in Details von der Microsoft-Implementierung abweichen. In der Praxis wird Ihnen aber nichts anderes übrig bleiben, als die konkret verfügbaren XML-Parser zu verwenden. Daher habe ich mich in diesem Kapitel dazu entschlossen, mit statt auf Trockenübungen gemäß dem W3C-Entwurf auf konkrete, für den Microsoft XML-Parser geschriebene Beispiele zu konzentrieren. Daher ist der auf den nachfolgenden Seiten auftauchende Begriff XML-Schema mit XDR-Schema synonym zu setzen. 5.2.1 Elemente und Attribute definieren Zentraler Teil eines XML-Schemas sind die Anweisungen, um zulässige Elemente einer XML-Dokumentklasse und die Attribute dieser Elemente zu vereinbaren. Im XDR-Schema werden folgende (vordefinierte) XMLElemente für die Definition benutzt: • <Schema> ist das Wurzelelement, welches die Schemadefinition aufnimmt. Das Element kennt das optionale Attribut name, welches den Schemanamen angibt sowie das Attribut xmlns, mit dem Verweise auf die Namensräume mit den Definitionen für die zulässigen Schemaelemente angegeben werden. Das Wurzelelement kann die Elemente ElementType, AttributType, element, attribute, datatype, description und group aufnehmen. • <ElementType> definiert den Typ eines XML-Elements für die Dokumentklasse. Das Element besitzt fünf mögliche Attribute content, name, type, model und order. Das Attribut name ist unbedingt erforderlich und vereinbart den Namen des Elements. Der Attributwert ist dabei vom Typ idref, d.h., der Name für einen Elementtyp muss im Schema eindeutig sein. Auf die Bedeutung der restlichen Attribute komme ich auf den folgenden Seiten noch zurück. Das Element ist ein Unterelement von Schema und kann die Unterelemente attribute, AttributeType, datatype, description, element sowie group enthalten. © Günter Born - www.borncity.de ICON: Hin XML-Schema 183 • <AttributeType> legt dagegen den Typ des Attributs für ein Element fest. Auch hier wird name benutzt, um den Namen des Attributs anzugeben. Zusätzlich sind die Angaben default, type, values und required zulässig, die Datentypen, Vorgabewerte etc. regeln. Diese Thematik wird weiter unten besprochen. Das Element darf Unterelement von Schema und ElementType sein und kann die Unterelemente datatype sowie description enthalten. • <element> dient dann dazu, die Instanzen der einzelnen Elemente zu vereinbaren (umgangssprachlich: Mit <element ...> geben Sie an, wo welches Element in der XML-Struktur auftreten darf). Das Attribut type dieses Elements bezeichnet den Elementtyp, der im <ElementType>-Tag definiert wurde. Zusätzliche Attribute erlauben, das Element als erforderlich festzulegen (siehe folgende Seiten). Das leere Element element ist Unterelement von ElementType und group. • <attribute> vereinbart die Attributinstanzen in den einzelnen Elementen. Das Attribut type dieses Elements bezeichnet den Attributtyp, der im <AttributeType>-Tag definiert wurde. Zusätzliche Optionen erlauben das Attribut für das Element als erforderlich festzulegen oder einen Standardwert vorzugeben (siehe folgende Seiten). Das leere Element attribute ist ein Unterelement von ElementType. • <datatype> erlaubt Ihnen, den Datentyp für Elemente oder Attribute festzulegen. Dieses Element besitzt nur das Attribut type, dessen Wert den Datentyp des Elements oder Attributs spezifiziert. Das leere Element ist ein Unterelement von ElementType und AttributeType. • <description> ist ein Element ohne weitere Attribute, welches einen Text mit einer Beschreibung aufnehmen kann. In dieser Art Kommentar können Hinweise für auswertende Werkzeuge hinterlegt werden. • <group> ist ein optionales Unterelement von <ElementType> und ermöglicht, den Inhalt in einer Sequenz zu organisieren. Zwischen Startund Endtag können Sie element- und description-Elemente einfügen, die ein Inhaltsmodell festlegen. <group> gibt dann an, wie die Elemente auftreten dürfen (einmal, mehrfach, Sequenz). Eine XDR-Schemadatei beginnt dabei mit der XML-Deklaration, gefolgt vom Schema-Element, welches den XML-Namensraum auf xmlns="urn:schemas-microsoft-com:xml-data" festlegt. <?xml version="1.0" encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xml-data"> Anschließend folgen die oben beschriebenen Elemente, mit denen das Schema für die XML-Dokumentklasse beschrieben wird. Dabei sind die Elementtypen über ElementType-Elemente festzulegen. Hierbei gilt, dass © Günter Born - www.borncity.de 184 Arbeiten mit XML-Schema (XDR) zuerst die inneren Elemente (die Elemente, die in der XML-Baumstruktur am weitesten vom Wurzelelement entfernt liegen) definiert werden. Zusätzlich werden die Inhalte der Elemente sowie die zugehörigen Attribute festgelegt. Diese Festlegungen erfolgen über vordefinierte Elemente des Namensraums xml-data sowie über Attribute dieser Elemente. Bei Attributdefinitionen ist es so, dass das AttributeType-Element sowohl innerhalb eines ElementType-Elements als auch global am Anfang der Schemadatei auftreten darf. Dies eröffnet Ihnen die Möglichkeit, einen Attributtyp global für das Dokument zu vereinbaren und dann den gewünschten Elementen über die <attribute>-Angabe in der ElementTypeDefinition zuzuordnen. Sie haben aber auch die Möglichkeit, lokale Attributtypen für ein Element in der ElementType-Definition zu definieren. Dies erlaubt Ihnen individuelle Attribute für die Elementtypen zu vereinbaren, die den gleichen Namen verwenden, aber eine unterschiedliche Bedeutung besitzen. Dies wird beispielsweise an der Struktur in Abbildung 5.3 deutlich. Das Attribut status wird einmal benutzt, um den Familienstatus der Person aufzunehmen. Gleichzeitig gibt es ein Attribut status des Elements daten, welches angibt, ob die Daten der XML-Datei geprüft (gültig) sind oder nicht. Auf den folgenden Seiten finden Sie ein Beispiel, das das entsprechende Schema definiert. © Günter Born - www.borncity.de XML-Schema 185 Abbildung 5.3: Schema mit Elementen und Attributen Beispiel: XML-Schema mit Elementen (ElementType) Für das erste Beispiel möchte ich nochmals die obige XML-Struktur verwenden, die nur aus Elementen ohne Attribute besteht: <daten> <person> <vorname>...</vorname> <name>...</name> <tel>...</tel> </person> </daten> Weiterhin werden für die Werte der Elemente keine besonderen Angaben bezüglich der Datentypen benutzt. Mit diesen Annahmen wird das XMLSchema sehr einfach. Zuerst sind die Elementtypen der inneren Elemente vorname, name und tel zu vereinbaren. <ElementType name="vorname"/> <ElementType name="name"/> <ElementType name="tel"/> Um das Beispiel möglichst einfach zu halten, wird in obigen Anweisungen nur der Name des Elements über das Attribut name festgelegt. Das Attribut name ist vom Datentyp idref, d.h., es © Günter Born - www.borncity.de ICON: Hin 186 Arbeiten mit XML-Schema (XDR) vereinbart einen eindeutigen Bezeichner innerhalb des Schemas. Das Attribut name muss unbedingt beim ElementType-Element angegeben werden. Dies macht auch Sinn, denn einmal legt das Attribut den Namen des Elements fest (ohne das Attribut würde dann so etwas wie <> vereinbart). Weiterhin darf ein Elementtyp innerhalb des Schemas genau einmal definiert werden, d.h., der Name muss eindeutig innerhalb des Schemas sein. Da diese Elemente in der XML-Struktur keine Unterelemente enthalten, greifen wir in der Definition auf Leerelemente zurück. Anschließend wird der Elementtyp person festgelegt. Auch hier gelangt das ElementType-Element zum Einsatz. <ElementType name="person"> <element type="vorname"/> <element type="name"/> <element type="tel"/> </ElementType> Allerdings ergibt sich eine Abweichung, da person ja die Unterelemente vorname, name und tel enthalten soll. Folglich werden zwischen Start- und Endtag die Elementinstanzen über das element-Element vereinbart. Dem Attribut type wird dann der Typ des Elements als Wert zugewiesen. Diese Typen wurden aber gerade über das ElementType-Element vereinbart. Mit <element type="vorname"/> legen Sie also eine Elementinstanz mit dem Typ vorname fest, die über ElementType vereinbart wurde. Die Elemente vorname, name und tel bilden den Inhalt des Elements person. Man sagt dann auch, dass die obige Deklaration mit <ElementType name="person"> ... </ElementType> das Inhaltsmodell (content model) für das Element person beschreibt. ICON: Hin Die Definition für das Wurzelelement daten samt Elementtyp und Inhaltsmodell erfolgt mit ähnlichen Anweisungen. Nachfolgend sehen Sie den gesamten Quellcode der Schemadatei: <?xml version='1.0' encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata"> <!-- Definition der inneren Elemente --> <ElementType name="vorname"/> <ElementType name="name"/> <ElementType name="tel"/> <!-- Jetzt kommt das äußere Element für Person --> <ElementType name="person"> <element type="vorname"/> © Günter Born - www.borncity.de ICON: Bei XML-Schema 187 <element type="name"/> <element type="tel"/> </ElementType> <!-- Und nun folgt das Wurzelelement --> <ElementType name="daten"> <element type="person"/> </ElementType> </Schema> Abbildung 5.4: Darstellung der XML-Daten, die das Schema benutzen (Internet Explorer 5.0) Im Ordner \Beisp\Kap05 der Begleit-CD finden Sie die Schemadatei person.xsd aus obigem Beispiel sowie die Beispieldatei Bsp05_02.xml. Laden Sie die XML-Dokumentdatei im Internet Explorer 5.x, sollte dieser den Dokumentinhalt aus Abbildung 5.4 zeigen. Beispiel: XML-Schema mit Elementen und Attributen Das nächste Beispiel erweitert die bisherige XML-Struktur um einige Attribute. Hierbei sollen dem Element person die Attribute für das © Günter Born - www.borncity.de ICON: Hin 188 Arbeiten mit XML-Schema (XDR) Geschlecht (hier als sex bezeichnet) sowie der Familienstatus (status) zugeordnet werden. Das Attribut status kommt aber auch (in einem anderen Kontext) im Element daten zum Einsatz. Dort zeigt es an, ob die Daten geprüft wurden. Die entsprechende Datenstruktur wurde bereits weiter oben in Abbildung 5.3 gezeigt. Schauen wir uns jetzt das Schema zur Definition der entsprechenden XML-Dokumentklasse an. <?xml version="1.0" encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata"> <!-- Definition der inneren Elementtypen (scope global) --> <ElementType name="vorname"/> <ElementType name="name"/> <ElementType name="tel"/> <!-- Definition eines Attributtyps (scope global) --> <AttributeType name="sex"/> <!-- Jetzt kommt das äußere Element für Personen --> <ElementType name="person"> <element type="vorname"/>>!-- Elementinstanzen --> <element type="name"/> <element type="tel"/> <!-- Definition des Attributtyps im Element (scope lokal) --> <AttributeType name="status"/> <attribute type="sex"/><!-- Attributinstanz --> <attribute type="status"/> </ElementType> <!-- Und nun folgt das Wurzelelement --> <ElementType name="daten"> <element type="person"/> <AttributeType name="status"/> <attribute type="status"/> </ElementType> </Schema> Die Anweisungen mit dem ElementType-Element kennen Sie bereits aus dem vorhergehenden Beispiel. Neu sind die AttributType-Elemente, die Attributtypen vereinbaren. Der Attributtyp sex wurde hier einmal global zu Beginn des Schemas vereinbart. Sie können daher Attribute dieses Typs in allen Elementen ohne weitere Deklaration mit dem <attribut>-Befehl einfügen. Dies sehen Sie beispielsweise im Inhaltsmodell des Elements person. Das Attribut status wird in unterschiedlichen Kontexten eingesetzt. Deshalb finden Sie das AttributType-Element sowohl im Inhaltsmodell des Elements person als auch im Inhaltsmodell des Elements daten. Die © Günter Born - www.borncity.de ICON: Bei XML-Schema 189 Attributinstanzen beziehen sich dann auf unterschiedliche Attributtypen, obwohl der gleiche Name status benutzt wird. Es bleibt natürlich an dieser Stelle die Frage, wie sinnvoll der gleiche Name für ein Attribut ist, welches unterschiedliche Bedeutung bei den jeweiligen Elementen besitzt. Aber es kann durchaus Fälle geben, wo dies gewollt ist (z.B. wenn Sie bei dem Attribut eines Elements den Wertebereich einschränken möchten oder müssen). Sie finden das Schema person1.xsd sowie die Beispieldatei Bsp05_03.xml im Ordner \Beisp\Kap05 auf der Begleit-CD. ICON: Hin ICON: Hin 5.2.2 Elementinhalte vereinbaren Bei einer DTD lässt sich angeben, welche Inhalte (Daten und/oder Unterelemente) ein Element haben darf. Weiterhin gibt es den Fall, dass ein Element leer ist. Etwas analoges lässt sich auch bei einer Schemadefinition erreichen. Hierzu verwenden Sie das Attribut content im ElementTypeElement. Die folgende Tabelle enthält die Werte, die vom Microsoft XMLParser für das content-Attribut in XDR-Schema definiert sind. Wert Bedeutung empty Es wird ein leeres Element vereinbart Schlüsselwort EMPTY in der DTD). textOnly Das Element kann nur Text, aber keine Elemente, aufnehmen (entspricht dem Schlüsselwort PCDATA in der DTD). eltOnly Das Element darf nur Unterelemente, die im Schema definiert sind, aufnehmen. mixed Das Element darf sowohl Text als auch benannte Elemente aufnehmen. (entspricht dem Tabelle 5.1: Werte für das content-Attribut im ElementType-Element Weiter unten lernen Sie, dass ein XDR-Schema ein offenes und ein geschlossenes Inhaltsmodell für ein Element vereinbaren kann. Bei einem offenen Inhaltsmodell kann der Typ textOnly neben Daten auch unbenannte Elemente (Elemente, die nicht im Inhaltsmodell vereinbart sind) enthalten. © Günter Born - www.borncity.de ICON: Ach 190 Arbeiten mit XML-Schema (XDR) 5.2.3 Datentypen für Elemente Im vorhergehenden Kapitel haben Sie gelernt, wie Sie einem XML-Element einen Datentyp zuordnen, der die zulässigen Daten vereinbart. Mit PCDATA konnten geparste Zeichenketten im Element hinterlegt werden. Ähnliches lässt sich auch für Elemente, die über ein Schema deklariert werden, vereinbaren. Die Festlegung des Datentyps erfolgt dabei über das Attribut mit dem Namen type. Allerdings sind einige Besonderheiten zu beachten. Um die Datentypen des Microsoft XML-Parsers in einem Schema zu nutzen, müssen Sie im Schema-Element einen Verweis auf den Namensraum hinterlegen, in dem die Datentypen vereinbart sind. Die betreffenden Anweisungen sehen dann für den Microsoft XML-Parser (Version 3) folgendermaßen aus: <Schema name="TestSchema" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes"> .... </Schema> Über xmlns:dt wird ein Präfix dt für den Namensraum vereinbart, über das die Datentypen referenziert werden können. Hier finden Sie ein schönes Beispiel für die Notwendigkeit solcher Namensräume. Wir haben zweimal das Attribut type, welches aber in verschiedenen Kontexten auftritt (einmal definiert es den Namen eines Attributtyps und einmal einen Datentyp). Um anschließend die beiden Attribute auseinander zu halten, werden Namensräume benutzt. Die Angabe xmlns= bewirkt, dass ein Standard-Namensraum angelegt wird (Sie brauchen keinen Namen vor Element- und Attributnamen zu setzen). Die Angabe xmlns:dt= vereinbart dagegen einen Namen dt für den betreffenden Namensraum. Im Schema können Sie dann das Präfix dt: vor Attribut- und Elementnamen setzen, um die Vereinbarungen dieses Namensraums zu identifizieren. Dies wird auf den folgenden Seiten noch etwas deutlicher. Um den Datentyp eines Elements per Schema zu vereinbaren, bietet Microsoft zwei Varianten an: • Sie können das Attribut mit dem Präfix für den vereinbarten Namensraum direkt als dt:type im ElementType-Element angeben. • Alternativ lässt sich das datatype-Element zur Vereinbarung des Datentyps verwenden, wobei dann das Attribut als dt:type in diesem Element auftritt. Diese beiden Varianten sind in den nachfolgenden Codezeilen abgebildet. <ElementType name="vorname" dt:type="string"> <ElementType name="age"> © Günter Born - www.borncity.de ICON: Hin XML-Schema 191 <datatype dt:type="int"/> </ElementType> In der ersten Zeile wird der Elementtyp mit dem Datentyp "string" vereinbart, während für den zweiten Elementtyp die Typdeklaration in einem getrennten <datatype>-Tag erfolgt. Sie erkennen dabei bereits, dass die SchemaDefinition wesentlich mehr Datentypen als eine DTD für Elemente zulässt. Die nachfolgende Tabelle führt die Datentypen auf, die von Microsoft für den eigenen XML-Parser bei Schemata implementiert sind. Wert Datentyp bin.base64 MIME kodierte Binärdaten im Base64-Format (Base64 ist eine Möglichkeit, Binärdaten als 7-Bit-Zeichen zu kodieren). bin.hex Hexadezimalzeichen, mit denen Binärdaten beschrieben werden. Jede Hexadezimalziffer repräsentiert ein Byte (8 Bit). boolean Logische Werte 0 (ist false bzw. falsch) oder 1 (ist true bzw. wahr). char Ein Zeichen (Zeichenkette der Länge 1). date Angabe als Untermenge des ISO 8601-Formats ohne die Zeitangabe (z.B. "1994-11-05"). Der Wert selbst wird nicht validiert, das Dokument kann also fehlerhafte Datumsangaben enthalten. dateTime Datumsangabe als Untermenge des ISO 8601-Formats mit optionaler Zeitangabe, aber ohne Zeitzone (z.B. "1988-0407T18:39:09"). Zeitangaben können bis Nanosekunden heruntergebrochen werden. dateTime.tz Datumsangabe als Untermenge des ISO 8601-Formats mit optionaler Zeitangabe und mit Zeitzone (z.B. "1988-0407T18:39:09-08:00"). Die Angabe -08:00 bedeutet, dass die aktuelle Zeitangabe 8 Stunden hinter der Greenwich-Zeit gelegt wird. Zeitangaben können bis Nanosekunden heruntergebrochen werden. fixed.14.4 Wie eine Zahl, aber nicht mehr als 14 Dezimalstellen links vom Dezimalpunkt und nicht mehr als 4 Nachkommastellen. float Realzahl mit keiner Begrenzung hinsichtlich der Stellenzahl (kann mit Vorzeichen, Wert und Exponent in f´der Form von 1.7976931348623157E+308 bis 2.2250738585072014E-308 angegeben werden). int Ganzzahl mit optionalem Vorzeichen. number Vorzeichenbehaftete Dezimalzahl im Intervall 1.7976931348623157E+308 bis 2.2250738585072014E-308. time Subset des ISO 8601-Formats ohne Datum und Zeitzone (z.B. "08:15:27"). © Günter Born - www.borncity.de 192 Arbeiten mit XML-Schema (XDR) time.tz Subset des ISO 8601-Formats ohne Datum, aber mit Zeitzone (z.B. "08:15:27-02:00"). i1 Integer mit Darstellung in einem Byte (z.B. "1", "127", "-128"). i2 2-Byte-Integer (z.B. "1, 703, -32768"). i4 4-Byte-Integer (z.B. "1, 703, -32768, 148343, -1000000000"). i8 8-Byte-Integer (Bereich 9.223.372.036.854.775.807). r4 4-Byte-Realzahl (7 Stellen Genauigkeit, Bereich 3.40282347E+38F bis 1.17549435E-38F). r8 Gleiche Zahlen wie bei float, vorzeichenbehaftete Realzahlen mit 15 Stellen Auflösung (Intervall 1.7976931348623157E+308 bis 2.2250738585072014E-308). ui1 Vorzeichenlose (unsigned) Integerzahl mit einem Byte Größe (z.B. "1, 255"). ui2 Vorzeichenlose (unsigned) Integerzahl mit zwei Bytes (z.B. "1, 255, 65535"). ui4 Vorzeichenlose (unsigned) Integerzahl mit vier Bytes (z.B. "1, 703, 3000000000"). ui8 Vorzeichenlose (unsigned) Integerzahl mit acht Bytes (bis 18.446.744.073.709.551.615). uri Universal Resource Identifier (URI). Ein URI gibt eine Adresse der Form "urn:schemas-microsoft-com:datatypes" an (z.B. urn:schemas-microsoft.com/Office9). uuid Steht für Unique Universal Identifier und beschreibt einen Bezeichner für ein registriertes OLE/COM-Objekt als Sequenz von Hexadeziminalzahlen. In der Sequenz sind immer 8 Bit (der 32-BitZahl) durch Bindestriche getrennt (z.B. "333C7BC4-460F-11D0BC04-0080C7055A83"). -9.223.372.036.854.775.808 bis Tabelle 5.2: XML-Datentypen (für das type-Attribute von Elementen) in Microsoft Schemas Neben diesen Microsoft-spezifischen Datentypen hat das W3C zusätzliche Datentypen wie entity, entities, enumeration (nur für Attributwerte), id, idref, idrefs, nmtoken, nmtokens, notation und string vereinbart. Diese werden in Microsofts XDR-Implementierung als primitive Datentypen aufgeführt. Die Bedeutung ist Ihnen bereits aus dem Kapitel zur DTD bekannt. Eine detailliertere Beschreibung der XML-Datentypen für Schemas wird von Microsoft in der Hilfedatei des Microsoft XML SDK (ab © Günter Born - www.borncity.de ICON: Hin XML-Schema 193 Version 2.5) angeboten. Sie können diesen SDK von msdn.microsoft.com/xml kostenlos herunterladen. 5.2.4 Reihenfolge (Order) der Elemente Die Reihenfolge der Elemente im XML-Dokument lässt sich gemäß den Ausführungen im vorhergehenden Kapitel über die DTD angeben. Etwas Ähnliches erlaubt das order-Attribut in einem Schema. Das Attribut darf die folgenden Werte aufnehmen: Wert Bedeutung one Erlaubt, dass nur ein Element einer Auswahl vorkommt. seq Das Element muss in der im Schema angegebenen Sequenz im übergeordneten Element auftreten. many Das Element darf keinmal oder mehrfach in beliebiger Reihenfolge auftreten. Dies ist die Standardvorgabe. Tabelle 5.3: Werte des order-Attributs Das Attribut order wird standardmäßig auf seq gesetzt, wenn das content-Attribut auf n Wert mixed aufweist. 5.2.5 Beispiel: Datentypen und Content festlegen An einem einfachen Schema möchte ich jetzt die Auswirkungen der bisher vorgestellten Attribute demonstrieren. Wir entwerfen eine XMLDokumentklasse zur Abbildung von Personendaten mit folgender Elementstruktur: <person> <vorname/> <name/> <tel/> <birth/> </person> Im Datensatz person werden Vorname, Name und Telefonnummer als Strings hinterlegt. Das Element birth enthält das Geburtsdatum im Datumsformat. © Günter Born - www.borncity.de ICON: Hin 194 Arbeiten mit XML-Schema (XDR) Abbildung 5.5: Eingabe der Datentypen im XML Spy-Editor Die Struktur dieser Dokumentklasse lässt sich mit einigen wenigen Anweisungen in einem Schema hinterlegen. In Abbildung 5.5 sehen Sie sogar, dass der bereits mehrfach erwähnte XML-Editor XML Spy das direkte Abrufen der Datentypen unterstützt. Sobald Sie ein Element eingeben, bietet dieser Editor Ihnen die Namen der verfügbaren Attribute an. Geben Sie den Namen eines Attributs vor, zeigt der Editor Ihnen bei der Eingabe des Werts dieses Attributs eine Liste der zulässigen Werte. In der Abbildung werden die von Microsoft unterstützten Datentypen eingeblendet. Sie können die Vorgaben dann direkt übernehmen. Der Aufbau der Schemadatei ist recht einfach. Um Datentypen nutzen zu können, muss im Schema-Element zusätzlich ein Namespace auf den URN datatypes definiert werden. Dies wird in folgender Zeile genutzt: <Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes"> Nach dieser Deklaration können Sie über das Präfix dt Datentypen mittels des type-Attributs zuordnen. Die folgende Anweisung vereinbart den Datentyp string für das Element vorname. Gleichzeitig wird über das Attribut content angegebenen, dass dieses Element nur Text (keine Elemente) aufnehmen kann: <ElementType name="vorname" dt:type="string" content="textOnly"/> © Günter Born - www.borncity.de XML-Schema 195 Alternativ können Sie auch das datatype-Element verwenden, um den Typ des Elements anzugeben. In diesem Fall ist es jedoch erforderlich, dass dieses Element durch ein ElementTyp-Element eingefasst wird: <ElementType name="birth" content="textOnly"> <datatype dt:type="date"/> </ElementType> Die obige Sequenz vereinbart den Datentyp date für das Element birth. Auf diese Weise können Sie die gewünschte Datenstruktur mit zusätzlichen Einschränkungen für die zulässigen Daten aufbauen. Nachfolgend sehen Sie das komplette Schema für die XML-Dokumentklasse. <?xml version="1.0" encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata" xmlns:dt="urn:schemas-microsoft-com:datatypes"> <!-- Definition der inneren Elementetypen (scope global) --> <ElementType name="vorname" dt:type="string" content="textOnly"/> <ElementType name="name" dt:type="string" content="textOnly"/> <ElementType name="tel" dt:type="string" content="textOnly"/> <ElementType name="birth" content="textOnly"> <datatype dt:type="date"/> </ElementType> <!-- Jetzt kommt das äußere Element für Personen --> <ElementType name="person" content="eltOnly"> <element type="vorname"/><!-- Elementinstanzen --> <element type="name"/> <element type="tel"/> <element type="birth"/> </ElementType> <!-- Und nun folgt das Wurzelelement --> <ElementType name="daten" content="eltOnly"> <element type="person"/> </ElementType> </Schema> Basierend auf diesem Schema können Sie nun XML-Dokumente erstellen und vom XML-Parser validieren lassen. Das folgende XML-Dokument lehnt sich an das obige Schema an, weist aber im zweiten Datensatz zwei Fehler auf: einmal ist die Reihenfolge der Elemente vertauscht, weiterhin ist das Datum in der falschen Notation angegeben. © Günter Born - www.borncity.de ICON: Bei 196 Arbeiten mit XML-Schema (XDR) Abbildung 5.6: Fehlermeldung beim Validieren des XMLDokuments <?xml version="1.0" encoding="ISO-8859-1"?> <daten xmlns="x-schema:datentypen.xsd"> <person> <vorname>Inge</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1980-10-05</birth> </person> <person> <name>Berninger</name> <vorname>Inge</vorname> <tel>089-333-4145</tel> <birth>20-03-1979</birth> </person> </daten> ICON: Bei Die betreffenden Anweisungen sind fett im Quellcode hervorgehoben. Laden Sie dieses XML-Dokument in einem validierenden Parser (z.B. im Microsoft Internet Explorer), wird dieser die falsche Anordnung der Elemente im zweiten Datensatz bemängeln. Korrigieren Sie diesen Fehler, bemängelt der Parser noch den Datumswert (Abbildung 5.6). Sie müssen diesen im Format "Jahr-Tag-Monat" schreiben. Der XML-Parser validiert (im Gegensatz zu den Aussagen der XML 2.5- bzw. 3.0 SDK-Hilfe) auch die Gültigkeit des Datums. Ein Datum wie der 30. Februar wird also nicht akzeptiert! Bei Ziffern muss ein Punkt als Dezimalpunkt angegeben werden. Sie finden die © Günter Born - www.borncity.de ICON: Hin XML-Schema 197 beiden Dateien Datentypen.xsd und Bsp05_04.xml im Ordner \Beisp\Kap05 auf der Begleit-CD. 5.2.6 Was sind offene und geschlossene Inhaltsmodelle? Weiter oben hatte ich ausgeführt, dass der Inhalt (präziser: das Inhaltsmodell) eines Elements über das element-Element beschrieben wird. Mit der Vorgabe <ElementType name="person" content="eltOnly"> <element type="vorname"/> <element type="name"/> ... </ElementType> geben Sie an, welche Elementtypen in einer Elementinstanz benutzt werden können; das content-Attribut legt ggf. fest, ob Elemente und Text gemischt werden dürfen. Beispiele sind weiter oben aufgeführt. Gemäß Ihrem bisherigen Wissen können XML-Dokumente nur solche Elemente bzw. Inhalte aufnehmen, die auch im Schema definiert sind. Bei XDR-Schemata muss dies aber nicht so sein, wie das folgende kleine Beispiel demonstriert. <?xml version="1.0" encoding="ISO-8859-1"?> <daten xmlns="x-schema:Datentypen.xsd"> <person> <vorname>Inge</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1980-10-05</birth>Text ist hier unzulässig! </person> <person> <vorname>Inge</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1970-12-19</birth> <vorname>Marianne</vorname> </person> </daten> Gemäß dem obigen Schema Datentypen darf das XML-Dokument nur in den Elementen der untersten Ebene (z.B. Name) Textdaten enthalten. Ein im Element person hinterlegter Text, müsste vom Parser abgewiesen werden. Weiterhin dürfte auch immer nur ein Element vorname in einem Element person auftreten. Bei Experimenten bin ich aber auf einen zuerst merkwürdigen Zusammenhang gestoßen. Das obige XML-Dokument wird als gültig ausgewiesen, obwohl die fett hervorgehobenen Stellen auf den ersten Blick eindeutig die Regeln im Schema verletzen. Wandeln Sie © Günter Born - www.borncity.de ICON: Bei 198 Arbeiten mit XML-Schema (XDR) dagegen das Dokument geringfügig ab, weist der Parser das XML-Dokument als ungültig zurück: <?xml version="1.0" encoding="ISO-8859-1"?> <daten xmlns="x-schema:Datentypen.xsd"> <person>Text ist hier unzulässig! <vorname>Inge</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1980-10-05</birth> </person> <person> <vorname>Inge</vorname> <vorname>Marianne</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1970-12-19</birth> </person> </daten> Hier wurde der Text direkt hinter dem Starttag <person> eingefügt und es treten zwei Elemente vorname auf. Zuerst glaubte ich an einen Fehler, später kam ich dann auf den wahren Grund: Im Gegensatz zu einer DTD erlaubt ein XDR-Schema dem XMLAutor, zusätzliche Elemente oder Attribute zum Dokument hinzuzufügen, die nicht im Schema deklariert sind. Das Verhalten des XML-Parsers im Hinblick auf undeklarierte Elemente können Sie über das von Microsoft vorgesehene Attribut model steuern. Dieses Attribut darf die Werte open und closed aufweisen, wobei standardmäßig der Wert open gilt. Die Dokumentation spricht dann von offenen und geschlossenen Inhaltsmodellen. Ist also kein Attribut open vorhanden (wie im Schema Datentype.xsd, das obigen Beispiel zugrunde liegt), wird ein offenes Inhaltsmodell angenommen. Bei einem offenen Inhaltsmodell dürfen Sie dann im XMLDokument zusätzliche Elemente und Daten einfügen (die nicht im XMLSchema definiert sind). Allerdings gibt es hierbei Verschiedenes zu beachten: • Inhalte, die die Definition eines Schemas verletzen, sind unzulässig. Dies erklärt beispielsweise, warum ein neues Element oder ein Text nicht zu Beginn einer Sequenz zulässig sind. Die Angabe <person>Dies ist ein Text <vorname>Marianne</vorname> <name>Hennsen</name> ... </person> muss daher bemängelt werden (das Schema schreibt vor, dass auf das Starttag <person> ein Element <vorname> folgen soll. © Günter Born - www.borncity.de ICON: Bei XML-Schema • 199 Sie haben aber z.B. die Möglichkeit, einen (im Schema undeklarierten) Text an das Ende der Struktur anzuhängen. <person> <vorname>Marianne</vorname> <name>Hennsen</name> ... Dies ist ein Text </person> Weiterhin dürfen Sie Elemente, die im Schema deklariert sind, an das Ende der Struktur anhängen (sofern dies nicht der Deklaration im Schema widerspricht). Die Vorgabe <person> <vorname>Marianne</vorname> <name>Hennsen</name> ... <vorname>Marianne</vorname> </person> ist daher zulässig. Weiterhin dürfen Sie undeklarierte Elemente und Attribute hinzufügen, sofern diese zu einem anderen Namensraum gehören. Wie dies funktioniert, wird in folgendem Beispiel gezeigt. <?xml version="1.0" encoding="ISO-8859-1"?> <daten xmlns="x-schema:Datentypen.xsd" xmlns:tt="urn:test"> <person> <vorname>Inge</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1980-10-05</birth>Text ist hier unzulässig! <vorname tt:ruf="ja">Marlies</vorname> <tt:fax>112</tt:fax> </person> </daten> Im Starttag des Elements daten finden Sie die Deklaration für die xmlnsAttribute. Das erste Attribut xmlns legt den Standard-Namespace fest, der für die Definitionen des Schemas Datentypen.xsd gilt. Das zweite Attribut xmlns vereinbart einen Namensraum tt, der auf irgendeine Deklaration verweist. Die Angabe urn:test macht an dieser Stelle keinen Sinn, da test nicht existiert (die Angabe kann also auch vom Parser nicht ausgewertet werden). Der Pfiff liegt aber darin, dass Sie anschließend beliebige Elemente oder Attribute aus diesem Namensraum im XML-Dokument einfügen dürfen. Sie müssen die betreffenden Namen lediglich durch das Präfix tt: kennzeichnen. Dies eröffnet einerseits eine hohe Flexibilität gegenüber DTD-basierenden XML-Dokumenten. Sie können dies an der Testdatei Bsp05_05.xml im Ordner \Beisp\Kap05 der Begleit-CD testen. Diese Datei sollte vom Browser © Günter Born - www.borncity.de ICON: Bei 200 Arbeiten mit XML-Schema (XDR) als gültig erkannt werden, sofern die Schemadatei Datentypen.xsd im gleichen Ordner hinterlegt ist. Andererseits birgt dies auch die Unsicherheit, dass die Dokumente als gültig klassifiziert werden, obwohl eine Übereinstimmung mit den Regeln des Schemas nicht gegeben ist. Um einen Aufbau gemäß Schema im XMLDokument zu erzwingen, verwenden Sie den Wert closed für das Attribut modell. Das model-Attribut lässt sich bei jedem ElementType-Element einfügen und legt fest, ob das Inhaltsmodell des betreffenden Elements offen oder geschlossen ist. Sie könnten daher erreichen, dass bestimmte Elemente als offen gelten, während andere Elemente samt Inhalt ein geschlossenes Inhaltsmodell (wie bei einer DTD) aufweisen. Sehen wir uns einmal das folgende XML-Dokument (Bsp05_05a.xml im Ordner \Beisp\Kap05 der Begleit-CD) an. <?xml version="1.0" encoding="ISO-8859-1"?> <daten xmlns="x-schema:Model.xsd" xmlns:tt="urn:test"> <person> <vorname>Inge</vorname> <name>Berninger</name> <tel>089-333-4145</tel> <birth>1980-10-05</birth>Text ist hier zulässig! <vorname tt:ruf="ja">Marlies</vorname> <tt:fax>112</tt:fax> </person> An dieser Stelle soll ein Text unzulässig sein. </daten> ICON: Bei Das Dokument weist nur einen Datensatz mit dem Element person auf. Das Element Daten soll eigentlich nur Unterelemente vom Typ person aufnehmen können, der Text in der vorletzten Zeile der Datei ist daher unzulässig. Andererseits sollen im Element person neben den im Schema deklarierten Elementen auch Texte und neue Elemente bzw. Attribute eintragbar sein. Ich habe die betreffenden Stellen im Quellcode hervorgehoben. Um dies im Schema zu hinterlegen, müssen Sie das modelAttribut mehrfach verwenden. Die nachfolgend gezeigte Datei Model.xsd findet sich auf der Begleit-CD-ROM im Ordner \Beisp\Kap05 und basiert auf dem Schema Datentypen.xsd. <?xml version="1.0" encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata" xmlns:dt="urn:schemas-microsoftcom:datatypes"> <!-- Definition der inneren Elementetypen (scope global) --> <ElementType name="vorname" © Günter Born - www.borncity.de ICON: Bei XML-Schema 201 dt:type="string" content="textOnly"/> <ElementType name="name" dt:type="string" content="textOnly"/> <ElementType name="tel" dt:type="string" content="textOnly"/> <ElementType name="birth" content="textOnly"> <datatype dt:type="date"/> </ElementType> <!-- Jetzt kommt das äußere Element für Personen --> <ElementType name="person" content="eltOnly" model="open"> <element type="vorname"/> <!-- Elementinstanzen --> <element type="name"/> <element type="tel"/> <element type="birth"/> </ElementType> <!-- Und nun folgt das Wurzelelement --> <ElementType name="daten" content="eltOnly" model="closed"> <element type="person"/> </ElementType> </Schema> Die beiden Instanzen des model-Attributs sind im Quellcode hervorgehoben. Im Element daten vereinbart das model-Attribut ein geschlossenes Inhaltsmodell. Der XML-Parser muss daher alle vom Schema abweichenden Elemente und Daten bei der Validierung abweisen. Folglich wird auch der Text im Element daten bei der Validierung als unzulässig bemängelt. Beim Element person soll es aber vereinbarungsgemäß zulässig sein, wenn der XML-Dokumentautor im Schema definierte Elemente an den Inhalt anhängt. Weiterhin darf er Attribute und Elemente aus einem anderen Namensraum sowie Textdaten in jeden Datensatz des Elements person aufnehmen. Daher wird bei der betreffenden ElementType-Deklaration das Attribut model auf open zurückgesetzt. Wenn Sie daher die Beispieldatei Bsp05_05a.xml mit der Schemadatei Model.xsd im Internet Explorer laden, darf dieser nur den Text im daten-Element bei der Validierung bemängeln. Der XML-Editor XML Spy konnte in der von mir benutzten Version das Dokument nicht validieren, da nicht alle Elemente implementiert wurden. Bei Experimenten mit XMLwriter musste ich feststellen, dass beim Aufruf des Parsers zur Validierung nicht immer korrekte Ergebnisse gemeldet wurden (erst nach einem erneuten Laden der Dokumente zeigte sich das erwartete Verhalten). Offenbar weisen beide Werkzeuge noch Fehler auf. © Günter Born - www.borncity.de ICON: Ach 202 Arbeiten mit XML-Schema (XDR) 5.2.7 Gruppierungen und Wiederholungen In Kapitel 4 haben Sie gelernt, wie Sie bei einer DTD Elemente als Sequenz oder als Auswahl vereinbaren (über ein Komma oder das Zeichen | als Separator). Weiterhin wurde dort gezeigt, wie sich Elemente als optional oder als erforderlich deklarieren lassen bzw. wie Elemente mehrfach im Dokument auftreten dürfen. Ähnliches lässt sich auch in Schemadateien erreichen, indem Sie in den Elementen ElementType und element die entsprechenden Attribute verwenden. Schauen wir uns einmal an, wie sich die Reihenfolge der Elemente beeinflussen lässt. <?xml version="1.0" encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata"> <!-- Definition der inneren Elementetypen (scope global) --> <ElementType name="vorname"/> <ElementType name="name"/> <ElementType name="tel"/> <ElementType name="email"/> <!-- Jetzt kommt das Element für Person --> <ElementType name="person" content="eltOnly" model="closed"> <group order="seq"> <element type="vorname" minOccurs="0"/> <element type="name"/> </group> <group order="one"> <element type="tel"/> <element type="email"/> </group> </ElementType> <!-- Und nun folgt das Wurzelelement --> <ElementType name="daten" content="eltOnly" order="many"> <element type="person"/> </ElementType> </Schema> Als Erstes fällt auf, dass im ElementType-Element mit der Personendefinition das neue group-Element auftritt. Sie können dieses Element zur Gruppierung von element-Einträgen verwenden (group wirkt dann so ähnlich wie die Klammern bei der DTD). Die Steuerung, wie Elemente im Dokument auftreten, erfolgt über das order-Attribut des ElementType-Elements. Dieses Attribut darf die Werte one, seq oder many aufweisen. Der Wert one besagt, dass nur eines der Elemente der Gruppe als Auswahl benutzt werden kann. © Günter Born - www.borncity.de ICON: Bei XML-Schema 203 <group order="one"> <element type="tel"/> <element type="email"/> </group> In obiger Sequenz wird festgelegt, dass entweder die Telefonnummer oder eine E-Mail-Adresse anzugeben ist. Beim Testen des betreffenden Schemas hatte ich jedoch zuerst keinen Erfolg; der Parser akzeptierte beide Elemente, egal wie der Wert von order gesetzt wurde. Erst als ich das Attribut model des Elements daten auf closed setzte, validierte der XML-Parser die XMLDokumente gemäß den Vorgaben im Schema. Dies zeigt die Tücken, die ein offenes Inhaltsmodell bietet. ICON: Ach Eine andere Variante besteht darin, dass einzelne Elemente als optional angegeben werden können. Nehmen wir den Datensatz einer Person, der aus Name und Vorname besteht. Dann wäre es durchaus möglich, den Vornamen optional zu halten, d.h., das Element entfällt. Die betreffende Deklaration im Schema sieht dann so aus: <group order="seq"> <element type="vorname" minOccurs="0"/> <element type="name"/> </group> Das Element group fasst die möglichen Elemente zu einer Gruppe zusammen. Durch order="seq" wird angegeben, dass der Inhalt der Gruppe in der angegebenen Reihenfolge im Dokument auftreten muss. Beim Element vorname wird aber das minOccurs-Attribut mit dem Wert 0 angegeben. Dies bedeutet, dass dieses Element auch 0-mal auftreten darf, d.h., das Element ist optional. Setzen Sie den Wert auf 1 (entspricht der Standardvorgabe), muss das Element einmal vorkommen. Wird das Attribut maxOccurs benutzt, lässt sich angeben, wie oft ein Element auftreten darf. Standard ist 1, ein Wert "*" erlaubt dagegen beliebig viele Instanzen des Elements. Der Standardwert * wird auch angenommen, falls content="mixed" für das Element gesetzt ist. Beide Attribute können sowohl im element- als auch im group-Tag auftreten. Sie können das Schema Order.xsd aus dem Ordner \Beisp\Kap05 der BegleitCD verwenden, um das folgende XML-Dokument validieren zu lassen. <?xml version="1.0" encoding="ISO-8859-1"?> <daten xmlns="x-schema:Order.xsd"> <person> <vorname>Ilse</vorname> <name>Braun</name> <tel>069-5555</tel> </person> © Günter Born - www.borncity.de ICON: Bei 204 Arbeiten mit XML-Schema (XDR) <person> <name>Hager</name> <!-- <tel>069-5555</tel> --> <email>[email protected]</email> </person> </daten> Im Dokument sind zwei Datensätze für Personen hinterlegt. Der erste Datensatz umfasst Name und Vorname der Person sowie deren Telefonnummer. Im zweiten Datensatz fehlt der Vorname und anstelle der Telefonnummer ist die E-Mail-Adresse hinterlegt. Das Element mit der Telefonnummer ist auskommentiert. Der Microsoft XML-Parser wird das Dokument als gültig erkennen. Erst wenn Sie das auskommentierte Element tel aktivieren, meldet der Parser einen Fehler (da tel und email durch one als Auswahl deklariert wurden). 5.2.8 Besonderheiten bei Attributen Ähnlich wie bei DTDs können Sie in einem Schema auch Attribute für die jeweiligen Elemente vereinbaren. Weiter oben haben Sie entsprechende Beispiele kennen gelernt. Bei der Definition des Attributs über das AttributeType-Element können Sie zusätzliche Optionen für das Attribut angeben. Diese Optionen werden über Attribute des attribute- und AttributeType-Elements definiert. Für das attribute-Element gelten folgende Optionen: • default: Dieses Attribut legt den Standardwert des deklarierten Attributs fest. • type: Der Wert dieses Attributs gibt den Attributnamen des deklarierten Attributs an. Dieser Name entspricht einem Namen in einer AttributeType-Definition. • required: Kann die Werte "yes" und "no" aufnehmen, die angeben, ob das Attribut angegeben werden muss oder nicht. Im AttributeType-Element dürfen die folgenden Optionen als Attribute des Elements angegebenen werden: • default: Dieses Attribut legt den Standardwert des deklarierten Attributs für diesen Attributtyp fest. Fehlt der default-Wert im attribute-Element, wird der in AttributeType vereinbarte Wert benutzt. Falls das Attribut als erforderlich vereinbart ist, muss der Vorgabewert in der Deklaration des attribute- oder AttributeType-Elements vereinbart werden. • dt:type: Dieses Attribut muss mit dem Präfix für den Namensraum datatypes versehen werden und definiert den Attributtyp der © Günter Born - www.borncity.de XML-Schema 205 Attributinstanz. Für Attribute sind nur die primitiven Datentypen entity, entities, enumeration, id, idref, idrefs, nmtoken, nmtokens, notation und string vorgesehen. • dt:values: Mit dieser Option legen Sie eine Auswahl an Werten für den Attributwert fest. • name: Definiert den Namen des Attributtyps. Dieser Wert wird im attribute-Element benutzt, um die Attributinstanz zu vereinbaren. • required: Kann die Werte "yes" und "no" aufnehmen, die angeben, ob das Attribut angegeben werden muss oder nicht. Die betreffenden Attributdeklarationen sind recht einfach, Sie müssen lediglich die entsprechenden Optionen als Attribute der Elemente attribute und AttributeType angeben. 5.2.9 Ein Beispiel für Attribute in Schemata Abschließend möchte ich ein Beispiel für die Verwendung von Attributen unter Verwendung verschiedener Optionen im Schema vorstellen. Es soll eine Autoliste als XML-Dokument aufgestellt werden. Der Besitzer der Liste hat jedoch eine Vorliebe für Autos in den Farben Rot, Blau und Gelb, d.h., es sollen sich keine Fahrzeuge anderer Farben eintragen lassen. Falls das Alter des Fahrzeugs bekannt ist, soll dieses auch aufgenommen werden. Um die Struktur möglichst einfach zu halten — wir sprechen ja gerade über Attribute — besteht jeder Eintrag nur aus einem Element name. Dieses Element nimmt die Daten des Fahrzeugs (das Modell) auf. Die Informationen über Farbe und Alter werden als Attribute des Elements hinterlegt, wobei farbe erforderlich, das Attribut alter aber optional ist. Das Schema für die entsprechende Datenstruktur sieht dann folgendermaßen aus: <?xml version="1.0" encoding="ISO-8859-1"?> <Schema xmlns="urn:schemas-microsoft-com:xmldata" xmlns:dt="urn:schemas-microsoft-com:datatypes"> <AttributeType name="farbe" dt:type="enumeration" dt:values="rot blau gelb"/> <AttributeType name="alter" dt:type="nmtoken" default="1"/> <!-- Definition der inneren Elementetypen (scope global) --> <ElementType name="name"> <attribute type="alter"/> <attribute type="farbe" required="yes"/> </ElementType> <!-- Jetzt kommt das Element für das Auto --> © Günter Born - www.borncity.de ICON: Bei 206 Arbeiten mit XML-Schema (XDR) <ElementType name="auto" content="eltOnly" model="closed"> <element type="name" maxOccurs="*" /> </ElementType> </Schema> Da nur ein Element in der Struktur zur Datenablage benutzt wird, benennen wir dieses Element mit name. Das Wurzelelement erhält den Namen auto. Um sicherzustellen, dass mehr als ein Element name im Dokument auftreten darf, wird in der <element .../>-Definition das Attribut maxOccurs="*" gesetzt. Das Element name wird dann über ein ElementType-Element vereinbart. Dieses Element definiert die beiden Attribute alter und farbe. Die Eigenschaften dieser beiden Attribute werden über <AttributeType .../>-Tags gesetzt. Mit <AttributeType name="farbe" dt:type="enumeration" dt:values="rot blau gelb"/> definieren Sie das Attribut farbe. Der Typ des Attributwerts wird auf enumeration gesetzt, um eine Auflistung von Farben im Attribut values angeben zu können. Die Werte sind in Anführungszeichen getrennt durch Leerzeichen anzugeben. Das Attribut alter wird auf ähnliche Weise definiert, wobei als Datentyp nmtoken gewählt wird. Der Attributwert wird über default auf den Wert 1 gesetzt. Basierend auf diesem XDR-Schema habe ich nachfolgend ein XML-Dokument mit drei Fahrzeugdatensätzen erzeugt. <?xml version="1.0" encoding="ISO-8859-1"?> <auto xmlns="x-schema:Attribute.xsd"> <name farbe="gelb">Opel Kadett</name> <name farbe="silber" alter="1">Mercedes SE 320</name> <name alter="8" farbe="blau">Ford Escord</name> </auto> ICON: Bei Wenn Sie dieses Dokument im XML-Parser validieren lassen, weist dieser den zweiten Datensatz ab, da die Farbe auf silber gesetzt wurde. Diese Farbe kommt aber in der Auflistung der für das Attribut gültigen Werte nicht vor. Sie müssen die Farbe auf Gelb setzen oder den Eintrag löschen, um eine gültige XML-Datei zu bekommen. Sie finden die beiden Dateien Bsp05_07.xml und Attribute.xsd im Ordner \Beisp\Kap05 auf der Begleit-CD. Zusammenfassung In diesem Kapitel haben ich Ihnen gezeigt, wie XML-Schemas (in der von Microsoft angebotenen Variante XDR-Schema) zur Definition einer Dokumentklasse herangezogen werden können. XML-Schemas haben den Vorteil, dass Sie die Struktur mit XML-Elementen beschreiben können. Außerdem haben Sie gesehen, dass ein XML-Schema verschiedene © Günter Born - www.borncity.de ICON: Hin XML-Schema 207 Möglichkeiten zur Erweiterung der Dokumentstruktur bietet. Neuere XML basierende Standards wie SOAP verwenden ebenfalls XML-Schema. Einziger Nachteil dieses Ansatzes: die bisher fehlende Unterstützung des W3C-Entwurfs zu XML-Schema durch Werkzeuge. Mit XDR-Schema liegt von Microsoft aber eine praktisch nutzbare Möglichkeit vor. Sofern Sie weitergehende Informationen benötigen, laden Sie sich die Dokument ezu XML-Schema von den W3C-Webseiten (www.w3c.org). Details zur Microsofts XDR-Schema bietet die Hilfedatei des Microsoft XML-SDK (msdn.microsoft.com/xml). Fragen 1. Nennen Sie einige Vorteile von XML-Schema gegenüber DTDs zur Beschreibung von XML-Dokumentklassen. 2. Mit welchen Elementen wird eine Elementinstanz im XDR-Schema vereinbart? 3. Wie werden Attribute im XDR-Schema deklariert? Antworten 1. XML-Schemas verwenden XML-Elemente und damit die gleiche Syntax zur Definition der Dokumentstruktur. XML-Schema bietet wesentlich mehr Datentypen als eine DTD. XML-Schema benutzt standardmäßig ein offenes Inhaltsmodell, d.h., Sie können die Struktur der XML-Klasse erweitern, ohne die Elemente deklarieren zu müssen. 2. Mit dem <ElementType>-Eintrag legen Sie eine Definition für einen Elementtyp ab. Die Elementinstanzen werden über <element> einem übergeordneten Element zugewiesen. 3. Attributtypen sind mit <AttributeType> zu definieren, die Zuweisung der Attribute erfolgt in den <ElementType>-Befehlen über <attribute>Einträge. © Günter Born - www.borncity.de