www.comelio-medien.com
XML Schema
Marco Skulschus Marcus Wiederstein Sarah Winterstone
XML Schema Marco Skulschus Marcus Wiederstein Sarah Winterstone
XML Schema
Marco Skulschus Marcus Wiederstein Sarah Winterstone
© Comelio Medien 2011
Alle Rechte vorbehalten. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Jeder Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Das gilt insbesondere für die Vervielfältigung, Übersetzung, Mikroverfilmung und die Einspeicherung und Verbreitung in elektronischen Systemen.
© Comelio GmbH Comelio GmbH Goethestr. 34 D-13086 Berlin Fon: +49 (0) 30-8 14 56 22-00 Fax: +49 (0) 30-8 14 56 22-10 www.comelio-medien.com
[email protected] Umschlaggestaltung, Comelio-Grafiken, Layout & Satz: Nadine Kilian Druck und Bindung: docupoint magdeburg, Otto-von-Guericke-Allee 14 39179 Barleben Printed in Germany
ISBN 978-3-939701-54-5
Inhaltsverzeichnis
Inhaltsverzeichnis
1. Elemente und Attribute 1. 1. Entwicklung von XML-Datenmodellen 1. 1. 1. Phasen in einem Entwicklungsprojekt 1. 1. 2. Prüfungsschema von XML-Dokumenten 1. 1. 3. Ansätze der Dokumentmodellierung 1. 1. 4. Eine Beispielanwendung 1. 2. Elemente und einfache Inhaltsmodelle definieren 1. 2. 1. XML Schema-Deklaration 1. 2. 2. Einfache und komplexe Elemente deklarieren 1. 2. 3. Verschachtelte Strukturen erzeugen 1. 3. Attribute deklarieren 1. 4. Lokale und globale Deklarationen 1. 4. 1. Globale Deklaration von Elementen 1. 4. 2. Globale Deklaration von Attributen 1. 4. 3. Allgemeine Überlegungen zu globalen Deklarationen 1. 4. 4. Attributorientierte Dokumente 2. Datentypen und Strukturen 2. 1. Vordefinierte Datentypen 2. 1. 1. Primitive Datentypen 2. 1. 2. Abgeleitete Datentypen 2. 1. 3. Listentypen und Schlüssel 2. 2. Deklaration einfacher Typen 2. 2. 1. Fassetten 2. 2. 2. Eigene Datentypen 2. 2. 3. Datentypdefinition durch Ableitung 2. 3. Reguläre Ausdrücke in XML Schema 2. 3. 1. Einfache Muster 2. 3. 2. Zusammengesetzte Muster
20 20 21 23 26 31 39 43 43 45 46 48 49 50 53 65 71 71 71 76 81 88 89 102 107 118 118 119
5
Inhaltsverzeichnis
2. 3. 3. Kurzschreibweisen 2. 3. 4. Mengenverarbeitung
122 126
3. Komplexe Typen und Inhaltsmodelle 3. 1. Deklaration von komplexen Typen 3. 1. 1. Lokale komplexe Typen 3. 1. 2. Einfaches Inhaltsmodell 3. 1. 3. Globale komplexe Typen 3. 2. Inhaltsmodelle 3. 2. 1. Einfache Inhalte 3. 2. 2. Komplexe Inhalte 3. 2. 3. Gruppenbildung 3. 3. Spezielle Inhaltsmodelle 3. 3. 1. Gemischte Inhaltsmodelle 3. 3. 2. Leere Inhaltsmodelle
128 128 128 134 141 155 155 163 169 179 179 185
4. Schlüssel und Verweise 4. 1. ID und IDREF/IDREFS 4. 1. 1. Schlüssel- und Verweisdefinition 4. 1. 2. Mehrfachverweise 4. 2. Key, Unique und Keyref 4. 2. 1. Schlüssel über 4. 2. 2. Eindeutigkeitsbeschränkung über 4. 2. 3. Verweise auf Schlüssel und Eindeutigkeitsbeschränkungen
193 193 194 199 203 203 214 220
5. Auslagerung und Wiederverwendung 5. 1. Inklusion 5. 1. 1. Einfache Wiederverwendung 5. 1. 2. Wiederverwendung mit Redefinition 5. 1. 3. Mehrstufige Inklusion und Namensräume 5. 2. Import von Strukturen 5. 2. 1. Grundprinzip des Imports 5. 2. 2. Übernahme ohne Namensraum 5. 2. 3. Import mit eigener Namensraumangabe
226 227 228 233 241 242 244 249 251
6. Gruppierungen und Ableitungskontrolle 6. 1. Verwendung von Gruppen 6. 1. 1. Element- und Attributgruppen 6. 1. 2. Ersetzungsgruppen für flexible Inhalte
255 255 258 262
6
Inhaltsverzeichnis
6. 2. Ableitungen kontrollieren 6. 2. 1. Grundproblem und Lösung 6. 2. 2. Vorgabemöglichkeiten 6. 2. 3. Ableitung beeinflussen
275 275 277 282
7. Namensräume 7. 1. Namensräume in XML 7. 1. 1. Verwendung eines einzigen Namensraums 7. 1. 2. Verwendung mehrerer Namensräume 7. 2. Deklaration von Namensräumen 7. 2. 1. Verwendung eines einzigen Namensraums 7. 2. 2. Verwendung mehrerer Namensräume 7. 3. Namensraum-Übernahme 7. 3. 1. Import 7. 3. 2. Keine Übernahme: Chamäleon-Design 7. 3. 3. Beliebige Komponenten akzeptieren
287 287 288 290 293 293 300 306 307 311 314
8. Dokumentmodellierung und erweiterbare Schemata 8. 1. Überlegungen zur Dokumentmodellierung 8. 1. 1. Abhängigkeit von Instanzdokument und Schema-Dokument 8. 1. 2. Typen von Syntax-Änderungen 8. 1. 3. Bedeutung der Dokumentmodellierung 8. 2. Benennung und Struktur von Elementen und Attributen 8. 2. 1. Überlegungen zur Element-Benennung 8. 2. 2. Überlegungen zur Attribut-Benennung und -Verwendung 8. 2. 3. Überlegungen zu Hierarchien 8. 2. 4. Design-Alternativen und erweiterbare Schemata
320 320 321 327 331 334 334 339 353 357
9. Dokumentation 9. 1. Möglichkeiten der Dokumentation 9. 1. 1. Einfache XML-Kommentare 9. 1. 2. XML Schema-Kommentar-Elemente 9. 1. 3. Einsatz von Fremd-Attributen 9. 2. Auslesen von Kommentaren 9. 2. 1. Auslesen von XML-Kommentaren 9. 2. 2. Auslesen von XML Schema-Kommentaren in Textdatei 9. 2. 3. Auslesen von XML Schema-Kommentaren in HTML 9. 2. 4. Auslesen von XHTML nach HTML 9. 2. 5. Auslesen von Fremd-Attributen
361 361 361 363 368 369 370 373 375 377 379
7
Inhaltsverzeichnis
10. DB-Datenmodellierung und XSLT-Transformation 10. 1. Datenmodellierung 10. 1. 1. Datenmodellierung mit Elementen und Attributen 10. 1. 2. Transformation in SQL 10. 2. XML Schema und Datenbanken 10. 2. 1. Einführung 10. 2. 2. Oracle 10. 2. 3. MS SQL Server
384 384 387 394 409 410 411 421
11. XML Schema und OOP 11. 1. XML Schema und Objektorientierung 11. 1. 1. Prinzip 11. 1. 2. Funktionsweise 11. 1. 3. Erweiterung auf Datenbanken 11. 2. XML Schema-Bindung in .NET 11. 2. 1. Prinzip der Klassengenerierung aus XML Schema 11. 2. 2. XML Schema-Bindung 11. 2. 3. Mapping und Serialisierung beeinflussen 11. 2. 4. Generierte Klassen erweitern 11. 2. 5. Von XML zu Objekten 11. 3. XML-Schema-Bindung in Java 11. 3. 1. Prinzip der Klassengenerierung aus XML Schema 11. 3. 2. XML Schema-Bindung 11. 3. 3. Mapping und Serialisierung beeinflussen 11. 3. 4. Von XML zu Objekten
429 429 430 433 436 439 439 442 444 451 452 456 457 459 462 470
8
Vorwort
Vorwort
Vorwort Herzlich willkommen zu einem Fachbuch aus dem Comelio GmbH-Verlag. Wir sind stets bemüht, Ihnen aktuelle Informationen rund um IT-Technologien in beispielorientierter und verständlicher Weise zu liefern, damit Sie auf diesem Wege in die Lage versetzt werden, Anforderungen mit neuen Werkzeugen umzusetzen.
Zu diesem Buch Dieses Buch handelt von der Modellierung und Beschreibung von Strukturen, die beim Datenaustausch zwischen Anwendungen und Rechnern benötigt werden. Dieser Datenaustausch kann in vielen Fällen besonders gut über XML (eXtensible Markup Language) durchgeführt werden. Mit dem vom W3C (World Wide Web Consortium, www.w3c. org)entwickelten XML Schema ist es möglich, überaus anspruchsvolle, in einzelne Komponenten zerlegbare und mit Datentypen versehene Regeldokumente zu entwerfen, die für die Entwicklung von Datenstrukturen im XML-Bereich und damit für die korrekte Verwendung – oder besser noch – für die Verwendung von korrekten XML-Dokumenten in Applikationen einsatzfähig sind.
Motivation Das XML Schema soll nicht nur die ehrwürdige DTD (Document Type Definition)1 der ersten Version von XML (XML 1.0) ersetzen, sondern hat dies bereits in vielen Bereichen getan und wird es in anderen noch tun. Sie geriet zeitgleich nicht nur durch das XML Schema in Bedrängnis, sondern auch durch die Microsoft-Varianten BizTalk-Schema und XDR(XML Data Reduced)-Schema, die mit dem XML Schema mittlerweile schon gar nicht mehr konkurrieren, sondern schon untergegangen sind. Im ersten Kapitel finden sich noch einige Beispielübertragungen mit der herkömmlichen DTD, da vielleicht einige Leser früher die DTD benutzt haben und nun umsteigen wollen. Die einzige weiterhin existierende Konkur-
1
10
Informationen zur DTD befinden sich in der XML-Spezifikation: http://www.w3.org/TR/xml11/
Vorwort
renztechnologie, die auch in einigen Punkten Vorteile bietet, ist RelaxNG2 von OASIS. Es ist allerdings bei Weitem nicht so weit verbreitet wie XML Schema. Im direkten Vergleich zwischen DTD, deren Syntax viele Leser vom ersten Kontakt mit XML her sicherlich kennen, und XML Schema lassen sich die Unterschiede bzw. Vorteile des XML Schemas hauptsächlich in zwei Punkten charakterisieren: ●●
Das XML Schema bietet für komplexe Anwendungen und Anforderungen geeignete Konstruktionen und eine umfangreiche Syntax. Sie überbietet die Möglichkeiten der DTD um ein Vielfaches, erlaubt die Definition von Datentypen, die Kombination von mehreren Schema-Dokumenten, die Entwicklung von komplexen Datenstrukturen und gestattet einen komponentenorientierten Aufbau von Schema-Dokumenten.
●●
Während die DTD aufgrund historischer Entwicklungen und der gemeinsamen Mutter SGML (Standard Generalized Markup Language)3 eine eigene Syntax besitzt, präsentiert sich das XML Schema als XML-Syntax mit eigenem Namensraum, aus dem sich die Elementnamen bedienen. Damit ist, wie auch schon für XSLT (eXtensible Stylesheet Language)4, eine XML-Technologie entwickelt worden, die selbst wieder auf der XML-Syntax beruht. Dadurch soll das Erlernen und das Verständnis diese Technologien vereinfacht werden.
Beispieldateien Für jedes in diesem Buch erstellte XML Schema-Dokument gibt es normalerweise auch ein Instanzdokument, also ein XML-Dokument mit beispielhaften Daten und einer korrekten Verwendung der im Schema-Dokument festgelegten Regeln. Nun kann man sich vorstellen, dass die Bereitstellung von Beispieldokumenten mit abwechselnden Inhalten eine zeitaufwändige Arbeit ist, die man leicht mit verschiedenen Hilfsmitteln automatisieren kann. Alles, was man dazu benötigt, ist eine Datenbank mit mehreren hunderttausend Datensätzen. Freundlicherweise stellte uns die RuhrFon GmbH ihre eigene Datenbank zur Verfügung. Sollten Sie von diesem Unternehmen noch nichts gehört haben, obwohl Sie im Ruhrgebiet wohnen, dann ist das nicht weiter von Bedeutung, denn diese Firma ist natürlich ebenso fiktiv wie es ihre Telekommunikations- und Kundendaten sind. 2 3
Nähere Informationen: http://relaxng.org/ Nähere Informationen: http://www.w3.org/MarkUp/SGML/ sowie zum Vergleich von XML und SGML: http:// www.w3.org/TR/NOTE-sgml-xml-971215 4 Nähere Informationen zur Technik: http://www.w3.org/Style/XSL/, zu XSLT: http://www.w3.org/TR/xslt, zu XSLFO: http://www.w3.org/TR/xsl/ und zu XPath: http://www.w3.org/TR/xpath
11
Vorwort
Wie Sie dem Datenmodell entnehmen können, gibt es Tabellen für Geschäfts- und Privatkunden, für Anrufe, für die Telefontarife, Rechnungen, die Rechnungsposten und schließlich für die Mitarbeiter, die all die vielen Daten kontrollieren und dafür sorgen, dass neue Kunden im Telefonnetzwerk miteinander telefonieren. Das Geschäftsmodell der Firma, die Sie in den Buchbeispielen näher kennen lernen werden, ist relativ simpel und baut ganz auf den im Internet hinlänglich bekannten Netzwerkeffekt auf, den man auch an der positiven Geschäftsentwicklung nachvollziehen kann. Ist man Teil des Netzwerks bzw. hat man ein Kundenkonto bei der RuhrFon GmbH, kann man über eine geeignete Vorwahl mit anderen Teilnehmern im Netzwerk telefonieren. Das heißt, es lohnt sich für private und geschäftliche Kunden, ihre Freunde und Geschäftspartner ebenfalls davon zu überzeugen, bei der RuhrFon GmbH Kunde zu werden, damit man im Freundeskreis günstig telefonieren kann.
Abbildung 0.1: Datenmodell für die Beispieldokumente
12
Vorwort
Aus den über eine Million Anrufen in zwei Jahren sowie den anderen in diesem Datenmodell vorhandenen Datenstrukturen wurden dann automatisch die XML-Beispieldokumente und dann ihre zugehörigen Regeldokumente erzeugt. Die in diesem Buch verwendeten, zahlreichen Beispiele können Sie von der Comelio Medien-Webseite herunterladen. Dort können Sie sich auch über evtl. Änderungen und Korrekturen sowie Neuauflagen dieses Buchs informieren. http://www.comelio-medien.com/ buch-katalog/xml/xml_schema
Schreibkonventionen Die vielen Beispiele in diesem Buch werden durch dicktengleiche Schrift ausgedrückt. Einige Stellen verdienen eine besondere Aufmerksamkeit Dies geschieht durch eine fette, dicktengleiche Schrift . Wichtige Begriffe, Datei- oder Ordnernamen sind in kursiver Schrift gekennzeichnet.
Weitere Informationen Bei einem so internetaffinen Thema gibt es eine Menge an Webadressen, die in Zusammenhang mit XML Schema von Bedeutung sind. Folgende Auswahl gibt einen kurzen Überblick zu Webressourcen und weiteren Informationsquellen. ●●
Offizielle Dokumente finden Sie auf den Seiten des W3C: www.w3c.org/TR/xmlschema-0/ (Einführungstext mit Beispielen) www.w3c.org/TR/xmlschema-1/ (Strukturen von XML Schema) www.w3c.org/TR/xmlschema-2/ (Datentypen von XML Schema)
●●
Seminare und Schulungen zu XML Schema und XML-Technologien: www.comelioseminare.com/deti3_XML.php.
●●
Kurzreferenzen zu vielen XML-Themen: http://www.comelio-medien.com/leserservice/kurz-referenzen
13
Vorwort
●●
Weitere Bücher bezüglich XML-Technologien bei Comelio Medien: XML: Standards und Technologien, ISBN 978-3-939701-21-7 XSLT, XPath und XQuery, ISBN 978-3-939701-18-7 XSL-FO, ISBN 978-3-939701-17-0 Oracle, PL/SQL und XML, ISBN 978-3-939701-10-1 MS SQL Server, XML und SOAP Web Services, ISBN 978-3-939701-03-3 PHP und XML, ISBN 978-3-939701-00-2
MS SQL Server: XML und SOAPWebservices
Oracle, PL/ SQL und XML
Verwendung von XML Datenbanken (Speicherung, Verarbeitung, Webservices) Standard: XSL-FO 1 0 Themen: PDF, Druckerzeugnisse
XSL-FO
Verwendung von XML in Programmiersprachen (Erzeugung, Verarbeitung, Transformation) XSLT, XPath und XQuery
PHP und XML
Standards: XSLT 1 0/2.0, XPath 1.0/2.0 und XQuery 1.0 Themen: HTML, Text, XML sowie allgemeiner Algorithmenentwurf
XML: Standards und Technologien
XHTML und CSS
Abbildung 0.2: Struktur der Reihe
14
Standard: XML Schema 1.1 Themen: Modellierung und Beschreibung von XML-Daten
XML Schema
Vorwort
Zielgruppe und Anwenderkreis Dieses Buch richtet sich an Entwickler, Analytiker und Entscheider, die XML in Anwendungen bzw. in Organisationen einführen und XML-basierte Datenströme beschreiben, erstellen und verarbeiten wollen. Auch wenn die Beispiele in diesem Buch immer in der Gestalt von Dokumenten erscheinen, die in einer einzelnen Datei untergebracht und als solche auch verarbeitbar sind, so muss dies nicht der Regelfall sein. Eine weitere Speichermöglichkeit bieten Datenbanken, wobei die Daten entweder objektrelational in geeigneten Spaltenstrukturen oder, um beim ersten Einsatzgebiet zu bleiben, direkt als Texte untergebracht sind. Sie können allerdings auch als Textstücke in Datenbankspalten oder anderen Zusammenhängen gespeichert oder erst durch entsprechende Anwendungen für den Datenaustausch generiert bzw. mit gerade im Kontext erzeugten Daten gefüllt werden. In diesen unterschiedlichen Zusammenhängen und Einsatzgebieten kann es sich dabei wiederum um interne Anwendungen zum Datenaustausch, der Datenhaltung, der Wissensrepräsentation oder der Vorstufe für unterschiedliche Ausgabeformate handeln, so wie dies auch in Anwendungen mit einer externen Ausrichtung der Fall sein kann, in der gleiche oder ähnliche bzw. veränderte Daten für die gleichen Zwecke verarbeitet werden sollen. Die Entscheidung, XML zu verwenden, ist für die Zielgruppe dieses Buchs schon gefallen (und ist es in wohl allen Fällen, in denen klassische kommagetrennte Werte oder andere Formate keine Lösung darstellen). In einem nächsten Schritt muss es nun in jedem XMLEntwicklungsprojekt darum gehen, herauszufinden, welche Datenstrukturen vorhanden sind, und wie diese zu modellieren sind. Dieses Buch vermittelt also keine Grund- oder Aufbaukenntnisse über die Verarbeitung von XML-Datenströmen mit z. B. XSLT oder über den Einsatz von XML in diversen Geschäftsmodellen oder Programmiersprachen, sondern beschäftigt sich ausschließlich mit der Entwicklung von Regeldokumenten. Dabei steht einerseits die Syntax von XML Schema im Rampenlicht. Sie wird bisweilen abgelöst von Entwicklungstechniken der Dokumentmodellierung, die mit XML Schema syntaktisch bzw. allgemein möglich sind. Dazu zählt vor allen Dingen die Entwicklung von wieder verwendbaren Komponenten.
Inhalt nach Kapiteln Die Themen der einzelnen Kapitel werden im Folgenden kurz aufgelistet: 1. Im ersten Kapitel lernen Sie, nach einer allgemeinen Einführung zum Thema XML Schema einfache XML-Dokumente zu modellieren und konzentrieren sich dabei auf
15
Vorwort
die Definition von Elementen und Attributen. Nach der Modellierung von lokalen Definitionen sehen Sie, wie sie globale Elemente und Attribute definieren, um sie dann mehrfach innerhalb anderer Strukturen zu referenzieren. 2. Das zweite Kapitel zeigt eine der wesentlichen Besonderheiten von XML Schema: das Datentypsystem. Sie lernen, für Werte von Attribute und Inhalte von Textknoten passende Datentypen aus der vorhandenen Typ-Bibliothek auszuwählen. Neben dieser umfassenden Datentyp-Bibliothek kann man auch spezialisiert Datentypen auf Basis der vorhandenen erstellen. Diese können entweder lokal und damit nur auf ein Element oder ein Attribut bezogen sein oder global erstellt werden, einen Namen erhalten und dann mehrfach in einem XML schema oder durch Einbindung auch in anderen XML Schema-Dokumenten verwendet werden. Das wichtigste Werkzeug für die Erstellung von solchen abgeleiteten Datentypen sind die Fassetten, welche verschiedene kombinierbare Wertebereichsbeschränkungen repräsentieren. 3. Im dritten Kapitel beschäftigen Sie sich mit Inhaltsmodellen, in denen Elemente in Reihenfolgen erscheinen oder die Alternativen sowie Auswahlen darstellen. Diese Inhaltsmodelle können unterschiedlich verschachtelt werden, sodass man eine große Anzahl an Kombinations- und Ausdrucksmöglichkeiten besitzt. Darüber hinaus kann man Strukturen in Form von so genannten globalen komplexen Typen auslagern und dann im selben oder auch in anderen XML Schema-Dokumenten wiederverwenden. Durch den Einsatz von Ableitung durch Einschränkung oder Erweiterung (Vererbung) kann man dann recht umfangreiche Modelle gestalten. 4. Das vierte Kapitel stellt einen Aspekt in den Vordergrund, der insbesondere bei der Modellierung von Datenbankmodellen mit Hilfe von XML Schema neben der Datentypsystematik wichtig ist, nämlich die Definition von Schlüsseln und Schlüsselverweisen/ Fremdschlüsseln. Dies wird entweder durch spezielle Elemente und XPath-Lokalisierungspfade realisiert oder durch DTD-konforme Datentypen, mit denen DTD-ähnliche Schlüssel- und Verweisstrukturen realisiert werden können. 5. Das fünfte Kapitel stellt die drei verschiedenen Varianten dar, mit denen XML SchemaBibliotheken modular aufgebaut werden können. Man unterscheidet hierbei zwischen Import, Einfügung und Redefinition. Bei der einfachen Einfügung gehen die ausgelagerten Elemente in den Namensraum des einfügenden Dokuments auf, während beim Import zu unterscheiden ist, ob die ausgelagerten Strukturen mit ihrem Namensraum eingefügt werden sollen oder ob diese Strukturen in den Namensraum des einfügenden Dokuments aufgehen sollen. Bei der Redefinition kann man die eingefügten Strukturen unter gleichem Namen auch noch inhaltlich verändern.
16
Vorwort
6. Im sechsten Kapitel lernt man die verschiedenen Konzepte kennen, die es ermöglichen, Strukturen auszulagern und sie abzuleiten. Dabei meint Ableitung die Erstellung neuer Strukturen auf Basis von vorhandenen, wobei eine Reihe von Veränderungen möglich sind. Man unterscheidet die beiden Varianten Ableitung durch Einschränkung und Ableitung durch Erweiterung. Wie die Namen schon sagen, können Elemente oder Attribute an bestehende Strukturen angehängt oder verboten werden. 7. Das siebte Kapitel führt die verschiedenen Techniken ein, mit denen Namensräume in einem XML Schema-Dokument verwendet und auch für die Verwendung in einem Instanzdokument definiert werden können. Hierbei beschäftigen Sie sich noch einmal mit der Technik der Namensräume in XML und sehen, wie Sie die unterschiedlichen Varianten (Standardnamensraum, ein einziger oder mehrere Namensräume) über XML Schema festlegen können. 8. Das achte Kapitel beschäftigt sich mit erweiterbaren Schemata, d. h. Überlegungen, welche die Veränderung von XML Schema-Strukturen und ihre Auswirkungen auf die Instanzdokumente oder das eigentliche Datenmodell bewirken. 9. Das neunte Kapitel zeigt schließlich verschiedene Elemente und Techniken, mit denen Dokumentationsinformationen in einem XML Schema-Dokument angegeben werden können. Es geht auch darauf ein, wie mit XSLT solchermaßen dokumentierten XML Schema-Dokumente in HTML-Dokumente umgewandelt werden können. 10. Das zehnte Kapitel zeigt, welche Möglichkeiten bestehen, XML Schema und Datenbanken gemeinsam zu verwenden. Hier gibt es zwei wichtige Optionen: Erstens kann man Datenmodelle für relationale Datenbanken mit XML Schema beschreiben. Wesentliche Techniken sind hier die vorhandene Typbibliothek und die Schlüssel-/Schlüsselverweise. Für die Erzeugung von SQL-Quelltext lernen Sie hier eine Lösung mit Hilfe von XSLT kennen. Zweitens kann man in XML-fähigen Datenbanken untypisiertes und typisiertes XML verwenden, wobei „typisiertes XML“ durch XML Schema validierte Daten darstellt. Für die beiden Datenbanken Oracle und MS SQL Server erhalten Sie eine Einführung über die Verwendung von XML Schema. 11. Im elften Kapitel wechseln Sie die Perspektive, wie Sie XML Schema betrachten. Es ist nämlich nicht nur möglich, XML Schema für die Modellierung von XML-Daten oder die Beschreibung von relationalen Datenstrukturen zu verwenden, sondern man kann auch objektorientierte Klassenstrukturen an XML Schema binden bzw. eine Zuordnung zwischen XML Schema-Definitionen und Klassenstrukturen schaffen. Für die beiden Programmiersprachen Java und .NET lernen Sie anhand von Beispielen die entspre-
17
Vorwort
chenden Bibliotheken kennen, um Klassen oder XML Schema-Dateien zu generieren sowie XML-Instanzdaten in Objekte umzuwandeln – oder wieder zurück.
Autoren Ein solches Werk schreibt man nicht alleine, sondern teilt sich die Arbeit nach Interessen und Schwerpunkten auf. Die Autoren arbeiten in verschiedenen Positionen bei Comelio (www.comelio.com) und haben bereits gemeinsam oder alleine verschiedene Bücher zu ihren Werkzeugen veröffentlicht. ●●
Marco Skulschus arbeitet als Projektleiter und Dozent bei der Comelio GmbH in Berlin und beschäftigt sich mit Berichts- und Expertensystemen auf Basis von MS SQL Server und Oracle. Er interessiert sich besonders für Ontologien und Data Mining-Techniken.
●●
Marcus Wiederstein arbeitet als Projektleiter bei der Comelio GmbH in Berlin für Projekte mit Microsoft-Produkten wie MS BizTalk Server, MS Sharepoint Portal Server oder MS Project Server sowie den Business Intelligence-Produkten.
●●
Sarah Winterstone arbeitet als Entwicklerin bei der Comelio, Inc. in Miami, FL und programmiert kaufmännische Anwendungen mit .NET und setzt dabei vielfältig XMLTechnologien ein. Ihr Spezialgebiet ist die Integration von XML in Datenbanken bzw. die Entwicklung von Import-/Export-Schnittstellen auf XML-Basis.
Sie erreichen das Sekretariat der Autoren unter der E-Mail-Adresse
[email protected]. Von dort werden Ihre Emails dann weitergeleitet. Die Webseite des Verlags finden Sie unter der Adresse http://www.comelio-medien.com. Auch in der realen Welt ist der Verlag zu erreichen. Die Hauptzentrale befindet sich in Berlin, Deutschland. Comelio GmbH, Goethestr. 34, D-13086 Berlin
18
Elemente und Attribute
1
1. Elemente und Attribute
1. Elemente und Attribute Ein Inhaltsmodell beschreibt den Inhalt eines Elements. Dabei kann es sich entweder um einen einfach typisierten Inhalt wie Zeichenketten oder Zahlen handeln oder um komplexen Inhalt wie Kind-Elemente oder Attribute. Diese möglichen Kind-Elemente besitzen dann ihrerseits jeweils ein Inhaltsmodell, sodass sich Ebene um Ebene die Regeln des Dokuments entfalten. Es ist syntaktisch leicht, in XML Schema solche Vorgaben zu treffen, aber deutlich schwieriger, Daten korrekt zu modellieren. Auch wenn wir zu diesem umfassenden Gebiet nur einen kurzen Einblick geben können, soll mit diesem Thema das Kapitel beginnen.
1. 1. Entwicklung von XML-Datenmodellen Eine Ihnen vermutlich auch geläufige Auszeichnungssprache ist HTML. Deren Syntax wurde in einem Schema-Dokument1 festgelegt, das theoretisch in jedem Browser gespeichert und mit Ausgabeformaten versehen ist. Dabei unterscheiden sich zwar in den einzelnen Browsern die tatsächlichen Anzeigeergebnisse, und man steht auch weiterhin bei einigen Tags vor der Hürde, dass sie in unterschiedlichen Browsern auf verschieden Weise angezeigt werden, aber grundsätzlich kann man HTML-Dokumente, die den Regeln im zugehörigen HTML-Regel-Dokument sich unterwerfen, in jedem Browser bzw. in jeder Anwendung, die HTML interpretieren kann, zum Einsatz bringen. So wie HTML nicht von Ihnen modelliert ist, so sind auch viele andere Grammatiken nicht von Ihnen modelliert, sondern von anderen Unternehmen, öffentlichen Behörden und sonstigen Gruppen. Beschäftigen Sie sich mit XML Schema, dann stehen Sie möglicherweise zum ersten Mal vor der Aufgabe, für XML-Daten eine Spezifikation selbst zu entwickeln.
1 Nähere Informationen zum Standard: http://www.w3.org/MarkUp/ und http://www.w3.org/TR/html4/ sowie zur DTD von HTML: http://www.w3.org/TR/REC-html40/sgml/dtd.html
20
1. Elemente und Attribute
1. 1. 1. Phasen in einem Entwicklungsprojekt XML2 ist die Antwort auf ein Hindernis oder eine Herausforderung, auf die jeder trifft, der sich in immer größeren Arbeitsumgebungen mit unterschiedlichen Konzepten der Datenhaltung und -speicherung sowie der Datenausgabe und -formatierung bewegt. Bei der Modellierung kann man die folgenden Teilbereiche und Aufgaben grob unterscheiden: ●●
Identifikation: Die anfallenden Elemente und ihre evtl. vorhandenen Varianten (evtl. über Attribute abzubilden), also die atomaren Bestandteile der Datenströme, müssen erkannt und klar festgelegt werden. Dazu zählt in einem ersten Schritt, überhaupt zu erkennen, welche Daten in allen oder einzelnen Situationen anfallen, oder ob es Situationen in Anwendungen oder Verarbeitungsprozessen gibt, die unterschiedliche Teilbereiche von Datenströmen benötigen und verarbeiten.
●●
Charakterisierung: Ihre Datentypen, möglichen Inhalte sowie eindeutige Namen und Kategorisierungen müssen beschrieben werden. Normalerweise sollten die Daten in einer atomisierten Form vorliegen, das heißt, in einer so kleinstrukturierten Form, dass weitere Unterteilungen nicht mehr möglich sind, sofern man nicht in Silben oder Buchstaben unterteilen würde. Dies gilt für gewöhnlich auch für den Datenbankeinsatz, da auch hier die Daten in einer atomisierten Form vorliegen sollten, um eine gute Speicherung und effektive Such- und Verarbeitungsalgorithmen zu gewährleisten.
●●
Verflechtung: Zusätzlich müssen die Beziehungen, in denen die Daten zueinander stehen, und ihre Abhängigkeiten untereinander beschrieben und verstanden werden. Die Elemente der Datenströme können in Abhängigkeit vom anwendungsspezifischen Kontext oder aufgrund von datenimmanenten Gegebenheiten mit unterschiedlicher Häufigkeit (mehrfach, gar nicht, einmal) auftreten.
●●
Entwicklung: Nach den Analysearbeiten steht die Entwicklung der Regelstrukturen an. Dabei geht es noch nicht notwendigerweise um die Entwicklung der eigentlichen Anwendung bzw. die konkrete Verwendung der Regel- und Instanzdokumente im durchzuführenden Projekt. Vielmehr handelt es sich bei der Entwicklung von SchemaDokumenten ebenfalls um einen analytischen Teilbereich oder eine Vorarbeit für die eigentliche Entwicklung einer Applikation.
2 Nähere Informationen zum Standard: http://www.w3.org/XML/ und http://www.w3.org/TR/2004/RECxml11-20040204/
21
1
1
1. Elemente und Attribute
●●
Validierung: Zum Schluss sollte – gerade bei größeren Projekten bzw. Projekten, in denen große Mengen an Datenströmen verwaltet werden, die Datenmengen erheblich und vielgestaltig sind oder in denen eine besondere Qualitätssicherung sowie eine nachhaltige und zukunftstaugliche Entwicklung gefordert wird – in einem letzten Schritt eine Kontrolle und Validierung stattfinden. Dies kann durch eine Prototypentwicklung oder durch die Verwendung der auf dem Regeldokument basierenden Instanzdokumente in einem vorhandenen Prototyp, der um die XML-Fähigkeiten erweitert wird, oder ganz einfach mit vorhandenen Daten geschehen.
Abbildung 1.1: Projektphasen bei XML-Einsatz
In einem letzten Schritt bzw. in der nächsten Phase des Software-Entwicklungsprozesses steht die Entwicklung der eigentlich geplanten Anwendung auf dem Zeitplan. Aus XML-Perspektive ergibt sich nun bereits eine längere Testphase, in der ungünstige Strukturen, nicht beachtete Sonderfälle oder ungewöhnliche Realdatengegebenheiten mit dem Regeldokument kollidieren. Durch derartige Rückmeldungen aus dem weiteren Entwicklungsverlauf lassen sich dann iterativ Veränderungen ableiten, die schließlich zum theoretisch korrekten Regeldokument führen. Des Weiteren werden nun auf der Basis des vorhandenen Schema-
22
1. Elemente und Attribute
Dokuments weitere XML-Technologien angewandt wie z. B. die Transformation mit XSL oder XSL-FO3 (Umwandlung in Druckdateien wie PDF4).
1. 1. 2. Prüfungsschema von XML-Dokumenten XML nun erlaubt die Definition eigener Auszeichnungsbefehle, die ausschließlich für die Textstruktur (und gerade nicht für Layout oder Darstellung) eingesetzt werden sollten. Zwar gibt es einige Praxisfälle, in denen auch Layoutregeln in XML umgesetzt werden, aber dies ist dann eher eine Modellierung von solchen Regeln zur strukturierten Erfassung und Verarbeitung. Handelt es sich nicht um abstrakte Speicherung für spätere Verarbeitung, sondern ähneln die Daten sehr existierenden Standards wie DocBook oder FO (Formatting Objets), sollte man eher auf solche Standards ausweichen und das Rad nicht neu erfinden. Es ist nicht immer leicht, Kunden, die Layout in XML unterbringen, vom Gegenteil zu überzeugen, können sie doch wunderbar mit XSL auf die Layoutregeln zugreifen, wodurch am Ende weiterhin wunderschöne PDF- und HTML-Dokumente entstehen. Aber für die Zukunftstauglichkeit und die langfristige Datenstrukturierung und -speicherung lohnt eine vollständige Trennung von Layout und Inhalt bzw. der Semantik mit Hilfe der XML-Dokumente und der XSL-Dokumente. Hier muss sprachlich noch einmal deutlich gesagt werden, dass es sich bei den XML-Dokumenten stets um Instanzdokumente handelt, die korrekt auf bereits existierenden Regeldokumenten beruhen. In Wirklichkeit gibt es ja nicht „das“ XML-Dokument, weil XML ja ausschließlich ein Konzept oder eine Technologie für die Verwendung und Entwicklung von eigenen Auszeichnungssprachen ist. Tatsächlich bezeichnet man ein XML-Dokument als ein solches, weil Textstücke mit Hilfe von Elementbezeichnungen in spitzen Klammern ausgezeichnet worden sind. Diese Syntax, also die Definition der verschiedenen Elementnamen etc., wiederum ist letztendlich immer in einem Regeldokument abgelegt, sodass vor der Verwendung eines Instanzdokumentes oder dem, was bis jetzt immer als XML-Dokument bezeichnet wurde, regelmäßig die Entwicklung eines Regeldokuments liegt. Abbildung 1.3 soll noch einmal die verschiedenen Dokumenttypen und deren jeweilige Aufgaben bei der Verwendung von XML kennzeichnen. Wie man sich leicht vorstellen kann, benötigt man in einer kompletten Anwendung noch mindestens ein Dokument mit entsprechendem Quelltext, das die Transformation startet oder mit den benötigten Parametern versorgt. Zusätzlich lassen sich weitere Dokumente und Strukturen aus dem XML-Umfeld denken wie z. B. solche mit semantischen Informationen oder solche, die zur semantischen 3 Nähere Informationen zum Standard: http://www.w3.org/TR/xsl/ 4 Nähere Informationen zum Standard: http://partners.adobe.com/asn/tech/pdf/specifications.jsp
23
1
1
1. Elemente und Attribute
Untersuchung und Abfrage von existierenden Instanzdokumenten dienen. Daher handelt es sich bei der Schemadarstellung um das Grundprinzip oder auch um die Minimalanforderungen einer XML-Anwendung mit den folgenden Dokumenttypen: ●●
XML-Instanzdokument: Es basiert auf einem Regeldokument und befolgt die dort genannten Strukturregeln in Hinblick auf das Vorkommen, die Häufigkeit und die Reihenfolge sowie die Benennung von Elementen sowie entsprechende Datentypen.
●●
XSD-Regeldokument: Es definiert die Strukturregeln im Hinblick auf das Vorkommen, die Häufigkeit und die Reihenfolge sowie die Benennung von Elementen sowie von entsprechenden Datentypen. Seine Inhalte sind bei der Prüfung wichtig, ob die Instanzdokumente sich an die getroffenen Regelungen halten, wobei die Prüfung für das XSL-Transformationsdokument sicherstellt, dass die Transformation durch den Zugriff auf die vorhandenen Elemente mit ihren sonstigen Eigenschaften erfolgreich verläuft.
●●
XSL-Transformationsdokument: In ihm sind die Transformationsregeln für die Umwandlung der XML-Datenströme in andere Formate enthalten. Es ist darauf angewiesen, dass die Regelungen im XSD-Regeldokument exakt eingehalten werden, da es selbst auf diese Regelungen zurückgreift, um Elemente zunächst zu identifizieren und dann auch zu verarbeiten.
Abbildung 1.2: Dokumenttypen und ihre Funktion bei XML-Verwendung
24
1. Elemente und Attribute
Für die Überprüfung gibt es zwei Dimensionen, in denen unterschiedliche Ergebnisse erreicht werden können: ●●
Wohlgeformt5: Ein XML-Dokument ist wohlgeformt, wenn die Syntax korrekt eingesetzt wird, d. h., Attribute in Anführungszeichen gesetzt, leere Elemente extra ausgezeichnet und die allgemeinen Regeln der Namenskonvention beachtet werden: Das erste Zeichen eines Namens muss ein Buchstabe, ein Unterstrich oder ein Doppelpunkt sein. Gültige Zeichen sind Buchstaben, Unterstriche, Ziffern, Bindestriche sowie Punkte und Doppelpunkte. Streng verboten ist die Verwendung des Wortes „XML“ in all seinen Varianten als Namensbeginn, da geschützt ist.
●●
Gültig6: Ein XML-Dokument ist gültig, wenn die benutzte Tag-Struktur der Anwendungslogik oder dem inhärenten Sinn des Dokuments genügt, d. h. soweit die Regelungen des Entwicklers erfüllt sind. Diese Regeln befinden sich in einem XML SchemaDokument.
Abbildung 1.3: Grundprinzip der Prüfung 5 Zur Definition: http://www.w3.org/TR/2004/REC-xml11-20040204/#sec-well-formed 6 ������������������������������������������������������������������������������������������������������ Zur Unterscheidung von Prozessoren: http://www.w3.org/TR/2004/REC-xml11-20040204/#proc-types sowie Unterscheidung beider Begriffe: http://www.w3.org/TR/xmlschema-1/#concepts-schemaConstraints
25
1
1
1. Elemente und Attribute
Ziel sollte also stets ein wohlgeformtes – da sonst ein allgemeiner Fehler auftritt – und gleichzeitig gültiges Dokument sein – da sonst ein spezieller Fehler in der Anwendungslogik auftritt. Im Ergebnis hat man also zwei Prüfungsschritte: zum einen die Prüfung auf Wohlgeformtheit (Syntaxprüfung) und zum anderen die Gültigkeitsprüfung (Verwendungsprüfung). Letztere muss nicht unbedingt erfolgen, da sie von der Existenz eines entsprechenden Schema-Dokuments mit Verwendungsangaben abhängt. Der Einsatz eines solchen Schema-Dokuments führt entweder zur Erkenntnis, dass das Instanzdokument gültig im Sinne des Schema-Dokuments ist oder nicht. Gültig und wohlgeformt sind also zur gleichen Zeit angestrebte Ziele, da sie zum einen nachweisen, dass die Regelungen des XML-Standards7 erfüllt sind und zum anderen die Regelungen des Schema-Dokuments befolgt wurden.
1. 1. 3. Ansätze der Dokumentmodellierung Die Erstellung eines einfachen Regeldokuments für eine Visitenkarte, eine Adressliste etc. ist natürlich keine wirklich schwere Aufgabe. Allerdings kann man auch bei der Verwaltung von Adressen bemerken, dass in verschiedenen Standardanwendungen im Office- oder Buchhaltungsbereich für die Erfassung der Adressdatenstruktur nicht nur fünf bis 10 Spalten wie in einem handelsüblichen Notizbuch bereit stehen, sondern teilweise mehr als 30. Teilweise sind diese dann auch nicht wirklich normalisiert, sondern im Hinblick auf wiederholende Einträge (alternative Email-Adressen oder Telefonnummern) auf eine bestimmte Anzahl von ähnlichen Einträgen begrenzt. Dies reicht zwar für 95% aller Eintragungen, aber bereits der Arbeitskollege mit Zweitwohnsitz im Ausland lässt sich mit seiner jeweiligen Mobil- und Festnetznummer nicht komplett erfassen. Dennoch kann man davon ausgehen, dass man für Datenstrukturen, die man sehr gut kennt, was natürlich bei solchen AlltagsDatenstrukturen wie Telefon- und Adressbuch der Fall sein dürfte, spontan und iterativ die korrekten Elemente und Strukturen entwickelt. Dabei würde man zunächst die unmittelbar und damit intuitiv einleuchtenden Elemente in einer vorläufigen hierarchischen Struktur und mit einer ebenso vorläufigen Häufigkeitsangabe erfassen. Durch einen iterativen Prozess aus der Validierung mittels Testdaten bzw. Verarbeitungsnotwendigkeiten oder Verarbeitungswünschen würde man danach in mehreren Schritten, die mit dem endgültigen XML Schema-Dokument terminierten, die weiteren Elemente der zu modellierenden Datenstruktur erfassen. Dieses Vorgehen scheint grundsätzliche Überlegungen, wie Datenstrukturen zu modellieren sind, vollkommen überflüssig zu machen bzw. nur darauf zu beschränken, eine bestimmten Syntax, wie in diesem 7
26
Vgl.: http://www.w3.org/TR/2004/REC-xml-20040204/
1. Elemente und Attribute
Fall jene vom XML Schema, für die Beschreibung der Strukturen einzusetzen. Tatsächlich aber gelingt und terminiert dieser spontane Ansatz nur deswegen erfolgreich mit einem XML Schema-Dokument, weil die Analysephase durch die Erfahrung im Umgang mit der zu modellierenden Datenstruktur überflüssig wird. Ganz anders hingegen stellt sich die Lage dar, wenn eine noch unbekannte Datenlandschaft modelliert werden soll, die zunächst einer Analyse und Darstellungsphase bedarf, in der grafisch die zu modellierenden Elemente umgesetzt werden. Zwei sehr einfache Möglichkeiten auf der Ebene der einfachen Tags und ihrer hierarchischen Beziehungen sowie der Anzahl von möglichen Unterelementen sind das Block- und das Baumdiagramm. Sie sollen auch gleich bei der Erstellung von gültigen und wohlgeformten XML-Dokumenten zum Einsatz kommen: In diesem Fall genügt die grundsätzliche Frage, welche Anforderungen an ein solches Dokument gestellt werden bzw. welche Informationen in welcher Hierarchie benutzt werden sollen. Sowohl der Blockdiagramm- als auch der Baumdiagramm-Ansatz stellen grafische Kodierungen bereit, mit denen Datenstrukturen, ihre Beziehungen untereinander, ihre Benennung und ihr Vorkommen und Auftreten symbolisiert werden können. Durch die Verwendung einer grafischen Notation erleichtert man auch den Mitarbeitern das Verständnis und stärkt ihre Integration in den Analyseprozess. In der Analysephase ist diese Integration alle Anstrengung wert, weil man auf den Erfahrungsschatz der Mitarbeiter stets zurückgreifen können sollte, um die zuvor erwähnten Vorteile durch die spontan-intuitive Methode der Dokumentmodellierung zu nutzen. Zwar muss hier der Analytiker, der auch als interner Mitarbeiter für ein entsprechendes, fachfremdes Projekt ein externer Berater ist, durch geeignete Moderation diese Erfahrungen freilegen und den Erkenntnis- und Validierungsprozess anleiten, aber durch eine ordentliche Integration der mit den Daten täglich umgehenden Organisationseinheiten (ganze Abteilungen, aber auch deren einzelne Mitarbeiter) erleichtert man die Entwicklung von komplexen Regeldokumenten, senkt die Fehlerquote und damit die Notwendigkeit, durch viele Rückkopplungen aus der Validierungsphase die fehlenden oder fehlerhaften Datenstrukturen zu erfassen. Nicht jede grafische Notation ist zwangsläufig einfach, so wie Schaltpläne auch nicht für jedermann ohne Anleitung und Vorwissen lesbar sind. Bei den im Folgenden vorgestellten Ansätzen jedoch ist die Wahrscheinlichkeit sehr hoch, dass nach einer kurzen Einarbeitungsphase in die Notationstechnik die gerade erwähnten positiven Effekte auch tatsächlich freigesetzt werden.
27
1
1
1. Elemente und Attribute
1. 1. 3. 1 Der Blockdiagramm-Ansatz Das Blockdiagramm bietet die Möglichkeit, sehr einfach und anschaulich von einem vorhandenem Dokument wie z. B. einem beliebigen Erfassungsbogen auszugehen und in ihm die einzelnen Einheiten und Abschnitte zu umrahmen, die ein Oberelement bzw. einen Auszeichnungsbefehl bilden könnten. Andersherum könnte bei der Erstellung eines Blockdiagramms ohne eine solche Vorlage vor dem inneren Auge des Betrachters ein entsprechendes Formblatt entstehen und wegen dieser Anschaulichkeit entsprechend assoziative Kräfte frei werden lassen, welche Texteinheiten noch mit diesem Dokument erfasst werden sollten. Man erhält also in beiden Bereichen eine mögliche Dokumentenstruktur mit einfachen grafischen Mitteln, die jeder unmittelbar oder höchstens nach einer sehr kurzen Einarbeitungszeit versteht. Bei der Datenmodellierung in einem ohnehin schon durch Formulare, Formblätter und Dokumentvorlagen gekennzeichneten Organisationsumfeld ist dies ein Ansatz, der bei einfachen oder flachen Datenbeziehungen ausreicht. In jedem Fall kann er in diesen Projekten aber auch als erster Schritt für eine Übertragung der vorhandenen Dokumente dienen, wobei die vorhandenen Vorlagen von den Datenstrukturen, die sie abbilden, getrennt werden. Dadurch können in Gesprächen, die während der gemeinsamen Erstellung des Diagramms stattfinden, auch Schwierigkeiten mit den vorhandenen Formularen berücksichtigt werden. Zu den klassischen Schwierigkeiten gehören hierbei fehlende Felder oder Daten, die handschriftlich immer zusätzlich eingetragen werden, Abkürzungen oder Textblöcke, die schematisiert einzutragen, aber nicht auszuwählen sind, oder auch Komplikationen bei der Verarbeitung von weichen Daten, die häufig auftreten, aber nicht in eines der vorgegeben harten Rasterfelder eingegeben werden können. Im Rahmen der Analyse sollte auch hier darauf geachtet werden, solche bestehenden Schwierigkeiten aufzudecken, die nicht mit der realen Datenstruktur unmittelbar, sondern eigentlich nur mit der bereits vorliegenden Ableitung aus der realen Datenstruktur zu tun haben, und verbessernd im XML-Projekt zu berücksichtigen. Durch den Blockdiagramm-Ansatz bzw. die Ähnlichkeit mit einem tatsächlichen Formular können auch leicht Validierungen vorgenommen werden. Das kann entweder mit Testoder Realdaten geschehen oder durch die Nachbildung eines typischen Verarbeitungsprozesses. Hier ist insbesondere wichtig zu ermitteln, wie verständlich und gut die Daten für nachfolgende Organisationsstellen und Verarbeitungseinheiten aufbereitet sind. Gerade für Mitarbeiter, die nur mit erfassten, nicht aber mit den real beobachteten Daten zu tun haben, ist dies ein entscheidender Faktor beim Umgang mit den vorliegenden Daten. Beide Dimensionen dürften dann neue Abhängigkeiten, Hierarchien oder Beziehungen und evtl. sogar benötigte Elemente offenbaren, die bisher noch keine Berücksichtigung fanden.
28
1. Elemente und Attribute
Abbildung 1.4: Blockdiagramm für eine Mitarbeiterdatenstruktur
1. 1. 3. 2 Baumdiagramm-Ansatz Eine Alternative zu diesem Vorgehen, das für sehr umfangreiche Dokumente mit vielen hierarchischen Beziehungen, die teilweise auch noch ungleichmäßig verteilt sind, besser geeignet ist, ist das Baumdiagramm. Hier hat man die Möglichkeit, sich von größeren Bereichen zu kleineren Einheiten durch die Anwendung zu arbeiten. Zudem kann man sehr einfach ganze Bereiche abdecken bzw. in Powerpoint ausblenden lassen, um einen speziellen Abschnitt des Baums ins Blickzentrum zu rücken. Dies ist im Blockdiagramm nicht möglich, da dann der entsprechende Bereich eine leere Fläche bildet und weiterhin stark auffällt. Um ein Dokument auf Gültigkeit hin zu prüfen, d. h., daraufhin zu testen, ob keine falsch überlappenden Abschnitte wie im folgenden Beispiel entstehen, genügt es beim Blockdiagramm, darauf zu achten, dass sich keine Blöcke überlagern. Beim Baumdiagramm hingegen dürfen sich keine Linien schneiden.
29
1
1
1. Elemente und Attribute
Abbildung 1.5: Baumdiagramm für Mitarbeiter-Datenstruktur
1. 1. 3. 3 Erweitertes Baumdiagramm Wir verwenden für die Darstellung eines realistischen Dokuments nun ausschließlich das Baumdiagramm, da es die Abhängigkeiten und Strukturen bei umfangreicheren Dokumenten doch etwas besser als ein Blockdiagramm versinnbildlicht. In einem erweiterten Schema wurden nun in die ursprüngliche Zeichnung folgende weiteren Elemente zur Planung eingebettet: ●●
Alle XML-Befehle werden in einem Rechteck dargestellt.
●●
Übergeordnete Tags, d. h., solche mit weiteren Untertags, erhalten eine graue Färbung, wobei allerdings keine weitere Unterscheidung über den Rang getroffen wird.
●●
Attribute werden direkt mit dem Tag verknüpft, zu dem sie gehören. Zusätzlich erhalten Sie einen gestrichelten Rahmen.
●●
Sich wiederholende Gruppen werden umrahmt. Dafür verzichtet man auf die explizite Nennung der Wiederholung durch mehrmalige Verwendung im Schema. Die Anzahl
30
1. Elemente und Attribute
der Wiederholungen kann dann durch einen Zahlwert oder durch eine nach oben offene Schranke in Form eines Plus-Zeichens dargestellt werden.
Abbildung 1.6: Erweitertes Baumdiagramm für Mitarbeiterliste
1. 1. 4. Eine Beispielanwendung Die oben theoretisch erläuterten Gedanken zur Notwendigkeit von Dokumentmodellierung soll nun an einem konkreten XML-Instanzdokument, einem Regeldokument in der XML Schema-Syntax und einem XSL-Dokument beispielhaft dargelegt werden. Hier spielen erstmals XML Schema und die Verknüpfung von Instanzdokument und Transformationsdokument eine Rolle. XSLT ist die Anwendung, die auf ein Instanzdokument zugreift und dabei prinzipiell darauf angewiesen ist, dass die Regelungen im Schema-Dokument tatsächlich auch im Instanzdokument erfüllt sind. Zwar ist es möglich, XSL-Dokumente auch so zu erstellen, dass sie relativ flexibel auf unterschiedliche Gegebenheiten in XML-Instanzdokumenten reagieren bzw. solche Unterschiede gar nicht bemerken. Sie können sogar, solange zumindest die Elementnamen nicht auch noch rücksichtslos verschieden im Vergleich zum Regeldokument sind, die gleiche Ausgabe erzeugen und trotz der Regelverstöße die Daten erfolgreich verarbeiten. Doch das ist in erster Linie eine Raffinesse von XSL und in zweiter Linie natürlich keine Anwendung mit hoher Qualität. Ausgehend von obiger Mitarbeiterliste folgt nun eine konkrete Mitarbeiterliste mit den zuvor genannten Elementen, wobei die Adressbestandteile zusammengestrichen wurden, um das Beispiel nicht unnötig kompliziert oder lang zu gestalten.
31
1
1
1. Elemente und Attribute
Anja
Doppelt
Technik
Reinhard Bergluft
Technik Marco Scheffchen Geschäftsführer 11_01.xml: Mitarbeiterliste mit drei Mitarbeitern
Ob man nun auf der Basis eines gegebenen XML-Dokuments ein mögliches Schema-Dokument erstellt, oder ob man zunächst die Dokumentmodellierung festlegt und dann gültige Instanzen erzeugt, hängt vom jeweiligen Projekt oder der Schwierigkeitsstufe ab. Jene Teilnehmer eines solchen Projekts, die eher beispielhaft denken und arbeiten und die lieber direkt mit den Daten bzw. Ergebnissen arbeiten, die ohnehin am häufigsten erstellt werden (in diesem Fall ja gültige Instanzdokumente und nur ein Regeldokument), werden sicherlich ein beispielhaftes Vorgehen schätzen und die Regelungen zunächst implizit gedanklich verwalten und nachher in die XML Schema-Syntax transferieren. So soll es auch in diesem Beispiel sein.
32
1. Elemente und Attribute
Ein Regeldokument, das also das obige Instanzdokument komplett charakterisiert und in diesem Sinne zu wenig Freiräume lässt, hat die nachfolgende Gestalt. Abgesehen von den Syntaxdetails und den naturgemäß vielen Verschachtelungen, die XML Schema-Dokumente (als kleine, unterschwellige Kritik) ohne Kommentierung oder Freizeilen bisweilen schwer lesbar machen können, sind folgende Regelungen erfasst: ●●
Das Wurzelelement heißt Mitarbeiterliste. Es enthält mehrere Unterelemente namens Mitarbeiter und sonst keine weiteren Inhalte.
●●
Das Element Mitarbeiter enthält die Elemente Name und Funktion.
●●
Das Element Name enthält die Elemente Vorname und Nachname in den Datentypen string sowie das verpflichtende Attribut Anrede, das nur die beiden Werte Herr oder Frau enthalten darf.
●●
Die beiden Elemente Vorname und Nachname wiederum enthalten – wie schon in den Datentypen dargelegt – Textwerte.
●●
Das Element Funktion hingegen enthält nur die beiden Textwerte Geschäftsführer oder Technik.
Wenn man die obigen Regelungen genauer betrachtet, fällt zuallererst auf, dass die gesamte Datenstruktur, die für die Erfassung und Verarbeitung von Mitarbeiterdaten bereit liegt und alleine schon in der Buchhaltung und für Sozial- und Krankenkassen benötigt wird, alles andere als vollständig ist. Es müssten noch diverse Zahlwerte die Sozialversicherungs- und Krankenkassennummern sowie das Geburtsdatum eingefügt werden, auf die jedoch in unserem Beispiel verzichtet wird, um keine Langeweile aufkommen zu lassen. Des Weiteren erkennt man, dass die Adresse komplett fehlt, was allerdings bereits zuvor ausgeschlossen war. Schließlich sind zwei Aufzählungstypen in die Regelungen eingearbeitet, von denen der eine die Werte im Attribut Anrede und der andere die Werte für das Element Funktion beschränken und vollständig abdecken. Während für die Anrede Herr und Frau ausreichen, ist es sehr unwahrscheinlich, dass der gesamte Mitarbeiterstamm aus Geschäftsführern und Technikern besteht. Theoretisch ist auch dies möglich, aber ein Blick in die Beispieldatenbank würde zeigen, dass auch andere Funktionen im Unternehmen angesiedelt sind.
33
1
1
1. Elemente und Attribute
34
1. Elemente und Attribute
11_01.xsd: Mögliches Regeldokument für Mitarbeiterliste
Als Grafik ohne Darstellung der Attribute erhält man folgende Repräsentation des abgedruckten XML Schema-Dokuments. Beachten Sie auch hier noch einmal, dass nur die Elemente Vorname, Nachname und Funktion Daten und keine weiteren Elemente enthalten.
Abbildung 1.7: Struktur des Regeldokuments für die Mitarbeiterliste
Bei der Datenverarbeitung, die in dieser Beispielanwendung durch ein XSL-Dokument als Transformationsdokument charakterisiert wird, greift man auf die gesamte Mitarbeiterliste zu und erstellt in der HTML-Ausgabe eine unsortierte Liste. Für jedes MitarbeiterElement wird hiernach ein Listenpunkt erzeugt, der als Wert die Elemente adressiert, die Textinhalte speichern. Diese werden in der Reihenfolge Vorname Nachname (Funktion) mit Klammerung und Leerstellen ausgegeben.
-
35
1
1
1. Elemente und Attribute
(
)
11_01.xsl: Transformationsdatei für Mitarbeiterliste
Als Ergebnis erhält man die in Abbildung 1.8 zu sehende Liste.
Abbildung 1.8: Ausgabe nach Transformation
Natürlich ist die Wahrscheinlichkeit, dass bei einer automatisierten Erzeugung von Instanzdokumenten Fehler wie die folgenden auftreten, sehr gering, aber durch entsprechend
36
1. Elemente und Attribute
falsch konstruierte Verarbeitungsbedingungen im Rahmen der Erstellung, können solche und andere Fehler entstehen. Wesentlich höher ist dagegen die Wahrscheinlichkeit, dass bei einer manuellen Erstellung von XML-Dokumenten ohne Editor mit automatischer Syntaxprüfung gerade Reihenfolge, Häufigkeit und Platzierung von Elementen misslingt, die ein entsprechender Editor zwar herausfinden und mokieren sollte, die aber bei ungeeigneten Editoren unbemerkt in das System gespeichert werden. Sobald eine solche Datei in der Anwendung mit XSLT verarbeitet wird, erhalten wir ein unschönes Ergebnis. Dies liegt nicht daran, dass XSL direkt auf die XML Schema-Datei zugreift, sondern dass das Transformationsdokument auf der Grundlage des Schemas erstellt wurde und die gegebenen Lokalisierungspfade im Instanzdokument für die Erzeugung des gewünschten Ergebnisses benötigt.
Anja Doppelt Technik Reinhard Jochen Bergluft Technik Marco Scheffchen Geschäftsführer 11_02.xml: Fehlerhaftes, demnach nicht gültiges XML-Instanzdokument
Als Ergebnis erhält man eine Ausgabe wie in Abbildung Abbildung 1.10: Transformationsergebnis eines fehlerhaften Instanzdokuments, wobei die korrekten Elemente und Strukturen
37
1
1
1. Elemente und Attribute
weiterhin korrekt ausgegeben werden, die falschen dagegen nach Vorgaben des Parsers bzw. so, wie ebenfalls im XSL-Dokument angegeben. Da mit Vorlagen wie
gearbeitet wird, wird überall dort, wo das Element Vorname zu finden ist, der entsprechende Wert des Vornamens ausgegeben. Dies entspricht einer Verarbeitung wie z. B. durch eine Iteration in der Form:
Hier geht man im XSL-Dokument (z. B. auf der Basis einer anders lautenden Regel) davon aus, dass mehrere Vorname-Elemente in Namen-Element auftreten können und für jedes der auftretenden Elemente eine Ausgabe bzw. zunächst der Aufruf einer passenden Vorlage erfolgen soll. So kann der zweite Vorname des zweiten Mitarbeiters korrekt mit vorgeschaltetem Leerzeichen ausgegeben werden. Die fehlenden Beginn- und Schlusstags für die ersten beiden Mitarbeiter-Elemente werden durch eine ähnliche allgemeine Vorlage im XSL-Dokument direkt nacheinander in einem Listenpunkt ausgeben. In beiden Fällen führt also die Flexibilität des XSL-Dokuments dazu, dass Textinhalte ausgegeben werden, im ersten Fall korrekt bzw. die Anwendung nicht störend, im zweiten Fall dagegen mit einer völlig falschen Gesamtausgabe, weil zwei Mitarbeiter in einer Zeile stehen. Die Ausgabe des Wertes Technik im für das Regel- und XSL-Dokument überhaupt nicht bekannten Taetigkeit-Element leitet sich dagegen aus den Voreinstellungen des Parsers ab, der einfach alle Textelemente ausgibt, sobald ihr Elternelement lokalisiert wurde und für sie keine weiteren Vorlagen erkennbar sind. Als Standardvorlage gilt dann die einfache Textausgabe. Dies mag teilweise im Sinne der Anwendung sein, erfolgt allerdings in einem falschen Format, nämlich ohne die runden Klammern.
38
1. Elemente und Attribute
Abbildung 1.9: Transformationsergebnis eines fehlerhaften Instanzdokuments
Dieses Beispiel sollte für eine Anwendung, die XML-Datenströme verarbeitet, die Notwendigkeit zeigen, nur korrekte und demzufolge das Schema-Dokument beachtende Daten zu verwenden, da ansonsten die Verarbeitungserfolge der Anwendung anderen Regelungen wie flexibler XSL-Syntax oder Parservoreinstellungen überlassen werden.
1. 2. Elemente und einfache Inhaltsmodelle definieren Einfache Inhaltsmodelle bestehen zunächst nur aus einigen Angaben, die in jedem Regeldokument vorhanden sein müssen. Sie beantworten die folgenden einfachen Fragen: ●●
Identität: Welche Elemente erscheinen im Dokument? Wie heißen sie, und welche Inhaltsmodelle haben sie wiederum?
●●
Beziehungen: Zu welchen anderen Elementen stehen sie durch ihre Inhaltsmodelle, d. h. durch den Aufruf anderer Elemente als Inhalt, in Beziehung?
●●
Kardinalität: Wie oft treten die einzelnen Elemente alleine oder im Verbund bzw. in Gruppierungen auf? Sind sie obligatorisch, unbegrenzt oder optional zu verwenden?
●●
Reihenfolge: In welcher Reihenfolge treten die Elemente in ihrer jeweiligen Dokumentebene auf? In welche Reihenfolgebeziehung stehen sie zu anderen Elementen?
39
1
1
1. Elemente und Attribute
Dies sind die Minimalanforderungen von Inhaltsmodellen, die auch von der Document Type Definition abgedeckt werden. Techniken wie Schlüssel- und Fremdschlüsseldefinition sind in beiden Techniken vorhanden, zählen aber nicht zu den elementaren und wichtigsten Strukturen. Die Syntax des XML Schemas sieht noch weitere Konzepte wie Wiederverwendbarkeit und Komponentenbildung vor. In Abbildung 1.10 sind die vier oben genannten Konzepte noch einmal exemplarisch in einem XML-Dokument wiedergegeben. Mit den nummerierten Punkten sollen für die ausgewählten Äste im Dokumentbaum die Reihenfolgen, mit Hilfe der Rechtecke die ausgewählten Elemente und mit den grauen Pfeile die Beziehungen von ausgewählten Elementen bzw. innerhalb des ausgewählten Zweiges charakterisiert werden. Die Häufigkeit ergibt sich indirekt aus der Anzahl des Auftretens der einzelnen Elemente.
Abbildung 1.10: Minimalinformationen von Inhaltsmodellen
40
1. Elemente und Attribute
Wie der Abbildung unschwer entnommen werden kann, geht es in einem Einstiegsbeispiel um Preisinformationen. Diese drückt aus, dass man nach Vertragsschluss mit der RuhrFon GmbH zum Frühstückstarif zwischen 6 und 10 für einen Cent pro Minute mit anderen Kunden des Unternehmens telefonieren kann, wobei der Tarif für das erste Halbjahr 2003 gültig ist. Sie finden dies in der Datei 12_01.xml. Mit der traditionellen DTD-Syntax sähe ein Regel-Dokument folgendermaßen aus, wobei die einzelnen Elemente über ELEMENT definiert und dann ihr Inhaltsmodell innerhalb des Klammerausdrucks angegeben würde. Hier kann man durch die kompakte, da nicht XMLkonforme Schreibweise auch sehr gut die Verschachtelung der einzelnen Elemente erkennen. Dies meint z. B., dass im Element Tarif als einziger Inhalt die weiteren Elemente Name, Gueltigkeit und Preis zugelassen sind. Des Weiteren bedeuten die durch das Komma angegebene Reihenfolge der Elemente im Klammerausdruck und die fehlende Häufigkeitsangabe, dass die benannten Elemente in dieser Reihenfolge und jeweils genau einmal im Dokument erscheinen dürfen. Verfolgt man ausgehend vom Element Tarif den Zweig im Dokumentbaum Preisliste / Tarif / Name, so erkennt man, dass dieser Zweig mit dem Blatt Name und seinem Inhaltsmodell, in dem textueller Inhalt definiert wird, abgeschlossen wird. Über den Zweig Preisliste / Tarif / Gueltigkeit hingegen gelangt man zu einem Inhaltsmodell für Gueltigkeit, das wiederum zwei neue Elemente aufruft, die den Zweig weiter führen und schließlich erst über weitere Elemente, nämlich Von und Bis zu textuellem Inhalt und damit zum Ende des zweiten Zweiges führen.
Uhrzeit (Von, Bis)> Von (#PCDATA)> Bis (#PCDATA)>
12_01.DTD: Schema-Dokument in DTD-Syntax
Abbildung 1.11 soll für drei ausgewählte Zweige im Dokumentbaum sowohl die Elementreihenfolge als auch die Beziehungen und die in der DTD-Syntax verwendeten Schreibweise veranschaulichen. Für jedes Element, das in einem anderen Element als Teil seines Inhaltsmodells aufgerufen wird, müsste ein neuer Zweig definiert werden, weswegen aus Gründen der Übersichtlichkeit nur drei Wege ausgewählt wurden. Davon sind zwei sehr
41
1
1
1. Elemente und Attribute
kurz, wenn auch der zweite von ihnen bzw. der dritte insgesamt, sehr weit nach unten verzweigt, da syntaktisch die untergeordneten Elemente des zweiten Zweiges zuerst deklariert werden.
Abbildung 1.11: Ausgewählte Zweige im Dokumentbaum
Diese Vorüberlegungen dienten dazu, die nun folgende Übersetzung in die XML SchemaSyntax verständlicher zu machen, da – was schon als Charakteristikum angeführt wurde – die Schreibweise aufgrund der XML-Konformität gerade nicht so kompakt wie bei der DTD-Syntax ist.
42
1. Elemente und Attribute
1. 2. 1. XML Schema-Deklaration Ein XML Schema-Dokument ist ein gültiges XML-Dokument, während die Document Type Definition eine eigne Syntax besitzt. Beim XML Schema dagegen existieren zwar allerhand Elemente und Attribute und demnach eine eigene Grammatik, aber sie ist XML-konform und erleichtert dadurch Einsatz, Verständnis und sogar Verarbeitung als XML-Dokument für hochdynamische Lösungen. Insgesamt ergibt sich dabei folgende Grundsyntax – bestehend aus dem XML-Prolog und dem Wurzelelement xs:schema:
Die einzelnen Elemente entstammen dem Namensraum http://www.w3.org/2001/XMLSchema, der mit dem Präfix xs abgekürzt wird. Dieses Präfix verwendet man dann für alle folgenden Elemente dieses Namensraums. Das bedeutet für das Element, dass es mit seinem qualifizierten Elementnamen, bestehend aus praefix:elementname, aufgerufen wird. So besteht die Möglichkeit, Elemente und Attribute aus anderen Namensräumen für die Erweiterung von XM Schema zu eigenen Zwecken zu verwenden.
1. 2. 2. Einfache und komplexe Elemente deklarieren Die einzelnen Elemente lassen sich über den Elementnamen element8 deklarieren, wobei als obligatorisches Attribut name für die Speicherung des Namens steht. Für die Festlegung, welches Inhaltsmodell für dieses Element gilt, gibt es zwei Möglichkeiten: ●●
Als leeres Element bezieht es sich entweder auf einen vordefinierten oder abgeleiteten Datentyp und enthält die Werte als Inhaltsmodell, die dieser Datentyp speichert. Alternativ besteht die Möglichkeit, wiederverwendbare Komponenten zu konstruieren und diese dann als Datentyp aufzurufen. Auf diese Weise kann man Inhaltsmodelle konstruieren, die Elemente oder auch gemischte Inhaltsmodelle (Elemente und Text) enthalten, wobei aber die genaue Deklaration an anderer Stelle im XML Schema-Dokument steht. Für beide Varianten verwendet man das Attribut type, das den Datentyp aufruft.
8 Vgl. http://www.w3.org/TR/xmlschema-1/#cElement_Declarations
43
1
1
1. Elemente und Attribute
●●
Als Element bezieht es sich zwischen Start- und End-Tag auf die benötigten untergeordneten Elemente. Hierbei müssen syntaktisch weitere Strukturen aufgerufen werden, mit denen neben der Identität auch die Kardinalität und Häufigkeit angegeben werden können.
Im nächsten Ausschnitt definiert man unvollständig das Element Uhrzeit, das später weitere Element enthalten kann.
Für die Definition eines solchen komplexen Elements verwendet man das Element complexType. Es deutet schon der Name darauf hin, dass es auch ein weiteres Element namens simpleType gibt. Es umschließt die untergeordneten Elemente und die Angabe, wie diese Elemente verwendet werden können. In diesem Zusammenhang handelt es sich um das Element sequence, da die beiden untergeordneten Elemente Von und Bis in genau dieser Reihenfolge auftreten.
Abbildung 1.12: Definition eines komplexen Elements
44
1. Elemente und Attribute
1. 2. 3. Verschachtelte Strukturen erzeugen Abschließend besitzt das gesamte XML Schema folgendes Aussehen: In einer Preisliste befindet sich genau ein Tarif, der sich mit Hilfe der Elemente Name, Gueltigkeit und Preis beschreiben lässt. Während Name und Preis Zeichenketten als direkte Werte empfangen können, teilen sich die Informationen in Gueltigkeit in die beiden Bereiche Datum und Uhrzeit auf, die jeweils die Angaben Von und Bis für die Zeitbeschreibung benötigen.
Abbildung 1.13: Übersicht über Elemente in Tarifbeschreibung
Als XML Schema-Dokument führt dies zur folgenden Syntax:
45
1
1
1. Elemente und Attribute
12_01.xsd: Schema-Dokument für einen Tarif
1. 3. Attribute deklarieren Ausgehend vom letzten Beispiel muss man sich fragen, was in den anderen Stunden des Tages an Telefontarifen in der Preisliste der RuhrFon AG eingetragen ist. Zwar werden sie alle einen anderen Namen besitzen, doch da ja schon der Frühstückstarif nur im ersten Halbjahr 2003 gültig war, werden vermutlich im zweiten Halbjahr andere Preise und Zeitspannen gelten. Kurz gesagt: Ein klarer Primärschlüssel in Form eines Elements oder eines Attributs fehlt.
46
1. Elemente und Attribute
Im folgenden XML-Dokument wurde für das Element Tarif ein solches Attribut namens Nr eingefügt.
Frühstück ...
13_01.xml: Verwendung eines Attributs
Mit einem Blick zurück auf die DTD erinnert man sich, wie dort ein Attribut definiert wurde, nämlich über das Element ATTLIST, das den Namen des Elements aufrief, dem dieses Attribut zugeordnet werden sollte, gefolgt von den Angaben, die nur für das Attribut selbst wichtig waren: dessen Name, sein Inhaltsmodell und eine Angabe zur Verwendung. ... 13_01.dtd: Attributdefinition in DTD
In der XML Schema-Syntax gibt es für Attribute ein eigenes Element namens attribute9 mit unterschiedlichen eigenen Attributen, die zunächst einmal die Eigenschaften abdecken, die bereits in der DTD-Konzeption vorhanden waren, und dann einige weitere, die über DTD hinausgehen. Es gibt zwei Möglichkeiten, Attribute zu verwenden und zu deklarieren. ●●
Lokale Deklaration: Das Attribut erhält seine Eigenschaften direkt innerhalb eines komplexen Typs und ist auch nur dort gültig.
9 Vgl. http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations
47
1
1
1. Elemente und Attribute
●●
Globale Deklaration: Das Attribut wird außerhalb des komplexen Typs deklariert, welcher nur eine Referenz auf das global verfügbare Attribut besitzt, und kann daher von verschiedenen komplexen Typen aus aufgerufen werden.
Da im aktuellen Beispiel zunächst nur die einfacheren Möglichkeiten dargestellt werden sollen, definiert man das Attribut Nr lokal für den komplexen Typ Tarif. Da dieser alle anderen Elemente enthält, ändert sich zum vorherigen Quelltext nur eine einzige Zeile, nämlich die Zeile, in der das Attribut definiert wird.
... 13_01.xsd: Definition eines Attributs
1. 4. Lokale und globale Deklarationen Einer der entscheidenden Vorzüge von XML Schema, nämlich die Wiederverwendbarkeit von Komponenten, ist bereits mehrfach angesprochen worden. Es gibt unterschiedliche Möglichkeiten, diese Eigenschaft zu nutzen. In der ersten und einfachsten Variante kann man Elemente und Attribute global und nicht nur lokal deklarieren. Das bringt den Vorteil, bei gleich lautenden Komponenten mit gleichen Eigenschaften, diese Eigenschaft zentral
48
1. Elemente und Attribute
bzw. nur für die globale Deklaration pflegen und sie beliebig oft im Dokumentbaum einsetzen zu können, ohne dort jeweils die entsprechenden Korrekturen einbringen zu müssen. Dies spart zum einen Arbeitszeit, da Änderungen und Planungen nur an einer Stelle gepflegt werden müssen, und erhöht zum anderen auch die Qualität von Dokumentmodellen, da ähnliche Datenstrukturen daraufhin überprüft werden können, ob sie eventuell sogar die gleichen Eigenschaften haben, sodass man sie auch auf identische Weise modellieren kann.
1. 4. 1. Globale Deklaration von Elementen In den vorangehenden Beispielen existierten für die jeweiligen Elemente in den einzelnen komplexen Typen individuelle Definitionen von weiteren Elementen mit Hilfe des Elements element. Dies provozierte allerdings, dass die beiden Elemente Von und Bis, die jeweils im komplexen Typ für Datum und Uhrzeit auftraten, mit den gleichen Eigenschaften modelliert wurden. Wenn sie nun tatsächlich die gleichen Eigenschaften haben, dann kann man sie als globale Elemente auslagern und referenzieren. Haben sie aber unterschiedliche Eigenschaften wie einen anderen Datentyp oder ganz anderen Inhalt, dann können sie dennoch den Namen teilen, aber andere Definitionen besitzen. Zunächst nennt man außerhalb des Wurzelelements die global zu deklarierenden Elemente Bis und Von mit ihren jeweiligen Eigenschaften, die sich zurzeit nur darauf beschränken, irgendwelche Zeichenketten zu speichern. Zeichenketten deswegen, damit gleichzeitig die Uhrzeit in Form einer einfachen Stundenangabe und das Datum in Form eines TT.MM.JJJJDatums erfasst werden kann. An den Stellen, wo die Elemente nun fehlen, nämlich innerhalb der komplexen Typen von Datum und Uhrzeit, referenziert man die gerade deklarierten Elemente über das Element element, verzichtet allerdings auf das name-Attribut, sondern ruft das benötigte globale Element im ref-Attribut auf: .
49
1
1
1. Elemente und Attribute
...
... 14_01.xsd: Globale Definition von Elementen
1. 4. 2. Globale Deklaration von Attributen Wie gerade schon bei der Einführung von Attributen erwähnt, lassen sich auch Attribute entweder lokal oder global deklarieren, wobei analog zu den Elementen über das Attribut ref ein entsprechendes globales Attribut referenziert wird. Folgende XML-Datei, die einige Informationen über einen Anruf speichert, soll dazu als Beispiel dienen. Sie ist gleichzeitig auch ein Beispiel für die globale Definition von Elementen, da im wiederholt auftretenden Element Kunde die gleichen Datenstrukturen auftreten, allerdings mit völlig anderem Inhalt, der hier ausschließlich über die Attribute variiert wird. Mit Blick auf die Attribute ergeben sich zwei Erkenntnisse: Das Attribut Typ tritt zwar wie
50
1. Elemente und Attribute
die beiden Elemente Vorname und Nachname wiederholt im Dokument auf, muss aber – wie das gesamte Element Kunde – nur einmal definiert werden, da man eine entsprechende Häufigkeitsangabe treffen kann. Das Attribut Nr dagegen tritt sowohl in den jeweiligen Kunden-Elementen wie auch beim Tarif auf und kann also global deklariert werden. Hier sei noch gesagt, dass man natürlich auch alle anderen Elemente global deklarieren kann und dies sowohl aus syntaktischen als auch softwaretechnischen Gründen eine Überlegung wert ist. Deklariert man prinzipiell immer alle Schema-Komponenten global, schafft man konsequent wiederverwendbare Datenstrukturen, ohne gleichzeitig die Möglichkeit zu verlieren, Elemente mit gleichem Namen, aber anderen Inhalten, Datentypen etc. lokal zu deklarieren. Dies geschieht dann über eine andere Syntax. Zurzeit jedoch sollen stets nur die Komponenten global deklariert werden, die sich zum aktuellen Zeitpunkt bereits als Kandidaten für globale Komponenten unmittelbar aufdrängen. Josef Martin Gerard Diehm Mondschein1
1 69
14_02.xml: Anruf
Um Attribute global zu deklarieren, definiert man sie außerhalb des Wurzelelements bzw. des Elements, in dem sie global zur Verfügung stehen sollen. Die eigentliche Deklaration ändert sich nicht. Es ist demnach möglich, aus einer lokalen Deklaration durch Verschieben an eine geeignete andere Stelle eine globale Deklaration zu schaffen. An den vorher durch die lokale Deklaration besetzten Stellen platziert man dann wiederum das attribute-
51
1
1
1. Elemente und Attribute
Element, allerdings nun mit dem Attribut ref versehen, das auf das global verfügbare Attribut verweist: .
Abbildung 1.14: Element-Struktur eines Anrufs
Das zusätzlich für das Element Kunde eingefügte Attribut maxOccurs=“2“ gibt das maximale Auftreten und damit eine Schranke der Kardinalität an. Dieses und andere Attribute werden später noch ausführlich behandelt. Es dürfen deswegen nur zwei Kunden im Dokument erscheinen.
52
1. Elemente und Attribute
14_02.xsd: Globale Definition von Attributen
1. 4. 3. Allgemeine Überlegungen zu globalen Deklarationen Die Technik bzw. die Syntax, die bisher vorgestellt wurde, ist nicht sonderlich schwierig zu verstehen. Natürlich gibt es noch weitere Konstruktionsmöglichkeiten und mehr XML Schema-Elemente, um Inhaltsmodelle zu bestimmen, doch diese finden Sie in den nächsten Kapiteln. In diesem Abschnitt sollen zwei Fragen aufgeworfen werden, die abschließend oder als allgemeine Regel nur schwer zu beantworten sind. Diese beiden Fragen kreisen um das Verhältnis von Attribut und Element und um die Existenz allgemeiner Richtlinien für die Modellierung von Dokumenten. Beide Fragen lassen sich auf der Grundlage der beiden folgenden XML-Dokumente beantworten, die beide ähnliche Daten wie zuvor enthalten. Nun allerdings gibt es nicht nur einen Anruf, sondern zwei, aber es könnten natürlich auch beliebig viele sein wie z. B. alle Anrufe eines Kunden in einem Monat (Rechnung August) oder alle Anrufe von Kunden eines Tages zu einem bestimmten Tarif (Frühstückstarif wochentags im Vergleich zum Wochenende). Mit XSL könnte man dann automatisch Rechnungen oder Berichte generieren, die dann als Endergebnis einer möglichen Datenbankabfrage, die die Rohdaten geliefert hat, eine Anwendung beenden. Für beide Dokumente wurden zugehörige Schema-Dokumente erstellt, die als Diskussionsgrundlage für die Modellierung dienen sollen.
53
1
1
1. Elemente und Attribute
1. 4. 3. 1 Dokumenten- vs. Datenorientierung Bevor das Beispiel eingeführt und diskutiert wird, soll es zunächst um zwei Grundprinzipien der Dokumentmodellierung gehen. Die beiden Begriffe Dokumentenorientierung und Datenorientierung10 findet man in der Spezifikation der XML Schema-Datentypen als Adjektive, also als Beschreibung für das allgemeine Vorgehen oder für die Zielsetzung von Aktivitäten im Bereich der Modellierung. ●●
Dokumentenorientierung konzentriert sich eher auf die Bedeutung oder die Semantik von Daten und bringt typischerweise auch solche Elemente oder Attribute mit den folgenden Namen hervor: Betonung, Wichtigkeit oder Empfaenger oder Ergebnis.
●●
Datenorientierung konzentriert sich eher auf die Inhalte der zugrunde liegenden Datentypen und bringt typischerweise auch solche Elemente oder Attribute mit den folgenden Namen hervor: Kunde, Nr, Telefon, PLZ, Summe, Produkt.
Abbildung 1.15: Grundsätzliche Modellierungstechniken
Selbstverständlich fällt es schwer, für jeden Komponentennamen eindeutig anzugeben, ob er genau in die eine oder eher in die andere Kategorie fällt. Möglicherweise könnte man für alle Begriffe eine Tendenz angeben, die einen weichen Zugehörigkeitsgrad zur einen oder anderen Kategorie ausdrückt. 10 Vgl.: http://www.w3.org/TR/xmlschema-2/#purpose
54
1. Elemente und Attribute
Eindeutig scheint es bei solchen Namen wie Betonung oder Wichtigkeit zu sein, da man sich bereits vorstellen kann, wie ein XSL-Dokument nachher auf solche Textbereiche zugreift und aus ihnen ein oder ein -Element generiert bzw. in einem Element oder einem class-Attribut eine entsprechende CSS-Formatvorlage aufruft. Über den zugrunde liegenden Datentyp ist nicht viel bekannt; vermutlich können sowohl Zahlen als auch Texte oder ein Datum wichtig oder betont dargestellt werden. Hier wird es sich um eine dokumentenorientierte Modellierung handeln. Eindeutig scheint ebenso ein solches Element wie PLZ, bei dem man sich bereits bei der Übernahme aus Formularen oder auch einer Datenbank vorstellen kann, dass hier nur ein bestimmter Datentyp mit Einschränkungen (fünfstellig in Deutschland, vierstellig in Österreich und der Schweiz) gültig ist und die gesamte Anwendung eine Postleitzahl nicht verarbeiten kann, die „Graz“ lautet. Hier wird es sich um eine datenorientierte Modellierung handeln. Dann gibt es viele weitere, die genauso gut der einen wie in der anderen Kategorie zugehörig sein könnten. Heißt eine Tabelle in einer Datenbank KUNDE, so wäre ein Oberelement Kunde vermutlich eher datenorientiert. Gibt es dagegen gar keine Datenbank, und gibt es neben dem Element Kunde noch andere, die verschiedenen Rollenbezeichnungen für Menschen enthalten, und handelt es sich dabei auch noch um einen Vertrag, dann wäre es vermutlich eher der Dokumentenorientierung zuzuschreiben. Eine weitere Dimension neben dem Namen und der Funktion einer Komponenten, die oftmals bereits über den Namen erkennbar wird, stellt dagegen der konkrete XML-Einsatz selbst dar. Wie schon im letzten Beispiel zum Element Kunde hervortrat, schien eine Zugehörigkeit zur einen oder anderen Kategorie davon abhängig zu sein, in welchem Zusammenhang das spezielle Element eingesetzt wird. Da die Beispiele in diesem Buch immer als Dateien auftreten, ist es nur natürlich von Dokumenten und nicht von Datenströmen zu sprechen. Es würde eventuell sogar ein wenig schulmeisterlich wirken, ständig darauf hinzuweisen, dass auch Dokumente während einer Verarbeitung Datenströme sind und dass man daher besser von XML-Datenströmen sprechen sollte. An dieser Stelle ist es jedoch ganz wichtig festzuhalten, dass die Benennung von Elementen und ihren Eigenschaften in den Dimensionen Identität, Kardinalität, Beziehungen und Reihenfolge stark davon abhängt, welche Transformationen mit den Dokumenten durchgeführt werden sollen. Für eine Textausgabe eines „Dokuments“ sind natürlich solche Elemente wie Listenpunkt oder Betonung wichtig, für einen „Datenstrom“ dagegen, der von einer Datenbank zur anderen, von einem XML-fähigen Messgerät zu einer Anwendung etc. übertragen wird, sind dagegen die Datentypen besonders bedeutsam für eine Verarbeitung.
55
1
1
1. Elemente und Attribute
Die Beispiele in diesem Buch stammen alle direkt aus einer Datenbank und sind daher eher datenorientiert, wobei im nächsten, schon oben angekündigten Beispiel auch dokumentenorientierte Elemente verwendet werden.
1. 4. 3. 2 Attribut vs. Element In jedem XML-Seminar entsteht eine Diskussion darüber, wann ein Attribut und wann ein Element zu verwenden sei. Attribute kann man nämlich immer vermeiden und ausschließlich mit Elementen arbeiten. In folgenden Fällen jedoch ist die Verwendung von Attributen gut geeignet: ●●
Attribute ermöglich es, Elementen eine leicht andere Bedeutung zu geben oder zusätzliche Informationen bereitzustellen, die nur das spezielle Element betreffen und nicht seinen Inhalt. Dadurch kann man das gleiche Element in verschiedenen Zusammenhängen verwenden, und diese Zusammenhänge oder seinen jeweiligen Elementuntertyp durch ein Attribut kennzeichnen.
●●
Für Inhaltsmodelle, die nur aus Elementen bestehen, können über Attribute Parameter oder Metadaten mitgegeben werden, die für eine Verarbeitung oder für ein genaueres Verständnis eines Elements notwendig sind, aber keine eigentlichen Inhalte transportieren. Insbesondere für die Übergabe von Parametern ist dies ein geeigneter Weg, der auch in der XML Schema-Syntax zu beobachten ist. Verarbeitung meint hier nicht nur eine einfache Ausgabe, sondern z. B. eine Fallunterscheidungen in XSL, die genau auf diese Werte zugreift.
●●
Über Attribute lassen sich Zusatzinformationen angeben, die gleichermaßen auch als Elemente deklariert werden könnten, aber evtl. eine spezielle Bedeutung haben, die über die Bedeutung der anderen Elementinhalte hinausgeht. Sie könnten gleichermaßen für eine Verarbeitung wie für eine Kategorisierung verwendbar sein.
Es handelt sich also nicht um eine Frage des korrekten Designs, ein Attribut zu benutzen, da man es stets durch ein Element ersetzen kann. Ein Schema-Dokument ist nicht richtig oder falsch, weil ein Attribut und kein Element oder ein Element und kein Attribut zum Einsatz kommen, sondern es handelt sich um eine Frage der Modellierungsgüte oder -qualität. Durch ein Attribut lassen sich Elemente bspw. an mehreren Stellen in einem Schema-Dokument einsetzen, wobei sie je nach Kontext einen anderen Typ erhalten. Dieser Typ ließe sich natürlich auch als untergeordnetes Element im Inhalt des variierenden Elements aufrufen,
56
1. Elemente und Attribute
aber syntaktisch steht das Attribut dem Element näher als ein untergeordnetes Element. Dies deshalb, weil ein Attribut im günstigsten Fall in der gleichen Zeile, aber auf jeden Fall innerhalb der beiden spitzen Klammern auftritt, die für das Element verwendet werden. Dadurch tritt deutlich hervor, dass es sich bei dem Wert des Attributs nicht um einen einfachen Inhalt, sondern um einen Wert handelt, der dieses Element auf besondere Weise charakterisiert, typisiert oder kategorisiert. In den Beispielen in diesem Buch werden regelmäßig die Primärschlüsselwerte aus der Datenbank als Attribute verwendet, vorzugsweise bei dem Element, welches eine Datenstruktur abbildet, die auch so in der Datenbank vorhanden ist. Ein Kunde wird in einem Element Kunde gespeichert, und sein Primärschlüsselwert liegt im Attribut Nr für dieses Element und stellt kein eigenes Element wie Vorname, Nachname oder die Adressbestandteile dar.
Abbildung 1.16: Attribut-Typologie
Wenn Kunden eine natürliche Person sind, dann werden die Daten um eine Zusatzinformation bezüglich der Anrede ergänzt. Es handelt sich dabei natürlich um eine inhaltlich ganz andere Information, als dies bei Vor- und Nachname der Fall ist, vor allen Dingen, weil er deutlich weniger unterscheidbar ist. In einer durchschnittlichen Kundentabelle können genauso viel Männer wie Frauen gespeichert sein, aber nur ein paar Prozent werden sich den Vornamen teilen und noch weniger werden den gleichen Nachnamen besitzen. In diesem
57
1
1
1. Elemente und Attribute
Sinne ist die Anrede zwar eine wichtige Information, aber sie könnte als Element genauso gut platziert werden wie als Attribut. Allerdings ist es bereits für viele einfachen Anwendungen sehr wichtig, zu wissen, ob der gerade zu verarbeitende Kundendatensatz zu einem Mann oder einer Frau gehört. Ein triviales Beispiel ist die Auswahl von Textbausteinen in der Form „Sehr geehrter Herr “ oder „Sehr geehrte Frau “. In diesem Sinne könnte man dieses Attribut entweder zu den Attributen zählen, die ein Element in bestimmte (wenige, in diesem Falle zwei) Kategorien einordnen oder die für eine Verarbeitung wichtig sind. Während die seltener auftretenden und in Kombination sogar teilweise identifizierenden Vor- und Nachnamen bei einer möglichen Rechnungsausgabe einfach nur ihrer einfachen Ausgabe harren, greift man das entsprechende Transformationsdokument explizit auf das Attribut Anrede zu und wählt in Abhängigkeit seines Wertes einen Textbaustein aus. Dies kann man als so entscheidend erachten, dass man kein Element, sondern ein Attribut für die Abbildung benutzt. Da jedoch auch andere Eigenschaften mit diesem Attribut in Verbindung gebracht werden können und es sich letztendlich auch als Element nicht störend im Dokument ausnähme, wurde es auch in Abbildung 1.7 als Elementkandidat bezeichnet, der eine Zusatzinformation bereithält.
1. 4. 3. 3 Modellierungstechniken im Vergleich Die in diesem Kapitel bereits bekannte Anrufdatenstruktur soll nun noch einmal für einen Vergleich der verschiedenen Modellierungstechniken Gegenstand der Betrachtung werden. In einer ersten Variante folgt das weitestgehend bekannte Dokument aus dem letzten Abschnitt, allerdings so überarbeitet, dass nun tatsächlich eine Anrufliste denkbar ist. Ein neues Wurzelelement namens Anrufliste speichert beliebig viele Anruf-Elemente; in diesem konkreten Beispiel zwei. Die beiden Anrufe stammen aus der zugehörigen Datenbanktabelle und unterscheiden sich sowohl durch die natürlich unterschiedlichen Dateninhalte ihrer untergeordneten KindElemente, aber auch durch ein Attribut Nr, das den Primärschlüsselwert aus der Datenbank wiedergibt. Das gleiche Attribut mit gleicher Bedeutung ist auch in den jeweiligen KundeElementen zu finden, wobei hier noch weitere Attribute stehen. Es ist für eine Verarbeitung bzw. eine Zuordnung der Anrufrichtung und damit auch der Information, wer den im Element Summe ausgewiesenen Preis entrichten muss, überaus wichtig. Um zu erkennen, welches Kunde-Element den Anrufer und welches den Angerufenen enthält, setzt man hier ein Schaltattribut ein, das alle Elemente Kunde in eine von beiden Wertkategorien (Von oder Nach) einsortiert.
58
1. Elemente und Attribute
B. Brock Norbert Fahle Schicht2 1 8
14_03.xml: Anrufliste mit Schaltattributen
Abbildung 1.17: Modellierung über Schaltattribute und wiederholtem Aufruf eines typisierten ElternElements
m XSD-Dokument stellt sich die Modellierung weitestgehend einfach und vor allen Dingen knapp dar. Die Länge des Quelltextes liegt nur an den verschachtelten Start- und End-Tags der XML Schema-Syntax, aber nicht an der Vielzahl der zu modellierenden Elemente. Hier
59
1
1
1. Elemente und Attribute
greift man nämlich darauf zurück, dass für einen Anruf zwar zwei Kunde-Elemente benutzt werden, aber diese die gleiche Datenstruktur haben und sich – für die Verarbeitung überhaus wichtig – inhaltlich durch die beiden Werte Von und Nach im Attribut Typ unterscheiden. Die Zuordnung der beiden Kundendatenstrukturen erfolgt also nicht durch solche Eltern-Elemente wie Anrufer oder Angerufener, sondern ausschließlich über ein Attribut, das dem einzigen Eltern-Element mitgegeben wird.
14_03.xsd: Einsatz von globalen Definitionen und komplexen Typen
Kategorisierung über Elementname
Martin Fulland Gerard Diehm
Gleiche Datenstruktur
Abbildung 1.18: Modellierung mit Elementen (Datei 14_04.xml)
Ganz im Gegensatz dazu verwendet das zweite Beispiel als Eltern-Elemente für Anrufer und Angerufenen kein Attribut, sondern jeweils ein neues Eltern-Element Von und Nach. Dadurch erkennt man bereits am Elementnamen die Kategorie, zu der die untergeordnete Datenstruktur gehört. Man erkennt hier, wie einfach es ist, anstatt eines Attributs ein – und dazu noch eines mit dem Attributwert als Namen – Element einzusetzen. Weiterhin repräsentieren das Attribut Nr für die beiden Kundendatenstrukturen, die nun über unter-
61
1
1
1. Elemente und Attribute
schiedliche Elemente ausgezeichnet werden, und das Element Anruf den Primärschlüssel aus der Datenbank. Da in den beiden Fällen Von und Nach auf die gleichen Kind-Elemente Vorname und Nachname verwiesen wird, besteht die Möglichkeit, diese beiden Elemente so zu referenzieren, wie in diesem Kapitel bereits gezeigt. Dadurch verringert sich der Deklarationsaufwand, der durch die Abbildung der gleichen Datenstrukturen innerhalb von zwei unterschiedlich benannten Eltern-Elementen entsteht.
62
1. Elemente und Attribute
14_04.xsd: Dokumentenorientierung und Verwendung von globalen Definitionen
Eine abschließende Bewertung hängt von diversen Faktoren ab. Nicht zuletzt spielen individuelle Vorlieben und Vorstellungen eine Rolle, wie denn Dokumente zu modellieren seien und wie man es besser nicht machen sollte. Folgende Aspekte könnten hier eine Rolle spielen: ●●
Lesbarkeit: Zunächst einmal ist natürlich der eher dokumentenorientierte Ansatz mit den jeweils in einem eigenen Element untergebrachten Strukturen für Anrufer (Von) und Angerufenen (Nach) einfacher zu lesen. Es ist auf den ersten Blick zu erfassen, welche Bedeutung die beiden Kundendatensätze haben.
63
1
1
1. Elemente und Attribute
●●
Knotenlokalisierung: Die bessere Lesbarkeit schlägt sich auch in einem einfacheren XPath-Ausdruck wie z. B. Anrufliste/Anruf[@Nr=120]/Von nieder, um einen entsprechenden Kundendatensatz auszuwählen. Im datenorientierten Ansatz hingegen muss man erneut auf das Attribut Typ zugreifen, um einen gleichen Datensatz auszuwählen: Anrufliste/Anruf[@Nr=120]/Kunde[@Typ=”Von”]. Allerdings hat man die Möglichkeit, im datenorientierten Ansatz über Anrufliste/Anruf[@Nr=120]/ Kunde alle beteiligten Parteien eines Anrufs herauszugreifen, wohingehen man für die gleichen Knoten im dokumentenorientierten Ansatz die Ausdrücke Anrufliste/ Anruf[@Nr=120]/*[local-name()=”Von” or local-name()=”Nach”] oder Anrufliste/Anruf[@Nr=120]/*[position()
114
2. Datentypen und Strukturen
115
2. Datentypen und Strukturen
2
22_03.xsd: Überblick über Ableitungsmöglichkeiten
Wie schon oben kurz angedeutet, zeigt das gesamte Schema-Dokument auch zwei mögliche Auslagerungstechniken, die mit der bis jetzt vorgestellten Syntax bereits realisierbar sind. ●●
Zum einen lassen sich globale Deklarationen von Elementen und Attributen einrichten. Sie beinhalten bereits alle Eigenschaften, die für die später im Schema-Dokument benötigten Strukturen modelliert werden sollten. Über das ref-Attribut des attribute- oder element-Elements verweist man auf diese globalen Deklarationen und übernimmt ihre Eigenschaften.
●●
Zum anderen lassen sich globale Datentypen mit den Basistypen und Einschränkungen einrichten, die für die entsprechenden Elemente oder Attribute notwendig sind. Über das type-Attribute des attribute- oder element-Elements verweist man auf diese globalen Deklarationen und übernimmt ihre Eigenschaften.
Im aktuellen Beispiel findet man eine Kombination beider Techniken: Zwei globale ElementDeklaration verwenden einen global deklarierten Datentyp, wobei die global deklarierten Elemente nachher jeweils zweimal in unterschiedlichen Eltern-Elementen auftreten. Man kann sich leicht vorstellen, um wie viel Zeilen das gesamte Dokument länger geworden wäre, wenn man diese globalen Deklarationen für die Elemente und den Datentyp nicht vorgenommen hätte. Die jeweiligen Datentyp-Eigenschaften hätten sich insgesamt an vier
116
2. Datentypen und Strukturen
Stellen wieder gefunden, zwar leicht variiert, da keine Ableitung durch Vereinigung notwendig wäre, doch immerhin jeweils doppelt.
Abbildung 2.13: Globale Elemente und Datentypen
117
2
2. Datentypen und Strukturen
2
2. 3. Reguläre Ausdrücke in XML Schema In den verschiedenen Programmiersprachen werden reguläre Ausdrücke7 in unterschiedlichen Funktionen unterstützt. Mit ihrer Hilfe lassen sich Zeichenketten auf besondere Vorkommnisse und Eigenschaften hin genauer untersuchen, als es mit einer einfachen Unterzeichenkettenfunktion und einem simplen Vergleich möglich wäre. Es lassen sich Zahlen von Buchstaben trennen, Wertebereiche untersuchen, Alternativen angeben und hochkomplexe Untersuchungen an Zeichenketten durchführen. Der Einsatz in XML Schema ist natürlich nicht auf die Untersuchung von Zeichenketten hin ausgerichtet, um z. B. Fallunterscheidungen mit passenden Werten zu versehen, sondern konzentriert sich mangels Syntax für Fallunterscheidungen und ähnliche Konstruktionen auf die Validierung von Werten im Instanzdokument. Mit den regulären Ausdrücken in XML Schema ist man demnach in der Lage, weitere und sehr genaue Einschränkungen des Wertebereichs bei der Gestaltung von Datentypen vorzunehmen. Dabei wird die spezielle Schema-Komponente pattern mit dem Attribut value verwendet. Diese ist für die Speicherung der regulären Ausdrücke notwendig, die sich nahezu vollständig an die Möglichkeiten in anderen Programmiersprachen anlehnt. Aufgrund der großen Ähnlichkeit mit dem Einsatz von regulären Ausdrücken in anderen Zusammenhängen geht dieser Abschnitt nur auf die wesentlichen Bereiche ein und gibt jeweils ein kurzes Beispiel. Interessant sind insbesondere die allgemeinen Syntaxübersichten, die bereits erkennen lassen, wie umfangreich und raffiniert die Forderungen hinsichtlich der Gültigkeit von Werten für einen Textknoten sein können. Die Beispiele aus diesem Abschnitt findet man in der Datei 23_01.xsd.
2. 3. 1. Einfache Muster Wie kurz zuvor schon erwähnt, setzt man innerhalb einer Datentypangabe die spezielle Schema-Komponente pattern ein. Sie enthält ein Attribut namens value, das den regulären Ausdruck speichert. Der allereinfachste vorstellbare Fall ist der Test auf Wertgleichheit mit einem vorgegeben Wert. Dazu schreibt man den entsprechenden Wert direkt und ohne Unterscheidung zwischen Zeichenkette und Zahlen. Folgender Datentyp prüft also nur daraufhin, ob der Wert in einer Jahreszahl 2004 ist. 7 Vgl.: http://www.w3.org/TR/xmlschema-2/#regexs sowie als Beispiel http://www.w3.org/TR/xmlschema0/#regexAppendix
118
2. Datentypen und Strukturen
2
2. 3. 2. Zusammengesetzte Muster Interessant ist natürlich auch, wie man Werte miteinander kombinieren kann. Dies immer dann, wenn mehrere Werte gleichzeitig bzw. in Kombination (Wiederholung, Alternative) gültig sind und es sich nicht immer um die gleichen Zeichen, sondern um Zeichen aus einer Gruppe handelt. Für einfache zusammengesetzte Muster verwendet man verschiedene Meta-Zeichen, die weitestgehend auch in den allgemeinen Syntax-Übersichten in diesem Buch zum Einsatz kommen. ●●
Für die Häufigkeit bzw. die Angabe von Wiederholungen verwendet man die Zeichen Plus, Fragezeichen und Asteriskus: +, ? und * mit ähnlicher Bedeutung wie z. B. auch in der DTD. Diese Zeichen platziert man nach dem jeweiligen Zeichen, dessen Wiederholungseigenschaft gesetzt werden soll.
●●
Wichtig für die Verwendung von Meta-Zeichen als Vorgabewerte in einem Ausdruck ist das Entwerter-Zeichen, das wie sonst in den regulären Ausdrücken auch ein Rückstrich ist.
●●
Für die Festlegung von Mengen verwendet man alle Sorten von Klammern, wobei als eigentliche Meta-Zeichen nur die runden und eckigen Klammern gezählt werden. Mit den runden erzeugt man Gruppen, deren Elemente z. B. eine gemeinsame Wiederholungseigenschaft aufweisen oder die als Gruppe eine mögliche Alternative darstellen. Mit den eckigen Klammern gibt man Zeichenbereiche von Buchstaben oder Zahlen an, denen sich in den meisten Fällen noch ein Wiederholungszeichen anschließen muss. Für die Angabe von detaillierten Wiederholungen lässt sich noch eine besondere Syntax mit geschweiften Klammern verwenden.
●●
Für die Angabe von Alternativen verwendet man den senkrechten Strich. Dieses Zeichen tritt häufig auch in Zusammenhang mit runden Klammern auf, die Gruppen kennzeichnen.
119
2. Datentypen und Strukturen
2
Folgende Zeichen sind insgesamt vorhanden:
Zeichen
Beschreibung
Beispiel
Treffer
.
Findet jedes Zeichen
d.e
\ ?
Entwerter-Zeichen Kein oder ein Auftreten
\*\d*\* ef?c
*
Kein, ein- oder mehrmaliges Auftreten
ef*c
+
Ein- oder mehrmaliges Auftreten
ef+c
|
Oder
ef|cd
(
Beginn Gruppe
e(f|c)d
)
Ende Gruppe
e(f|c)d
[ ]
Beginn Bereich Ende Bereich
xx[E-Z]*xx xx[E-Z]*xx
dXe d5e *1234* ec efc ec efc efffffc efc efffffc ef cd efd ecd efd ecd xxEFCDxx xxEFCDxx
Tabelle 2.1: Meta-Zeichen
2. 3. 2. 1 Alternativen Stehen mehrer Werte alternativ als korrekt zur Verfügung, so können sie im einfachsten Fall durch einen senkrechten Strich voneinander getrennt werden. So geschehen im Einstiegsbeispiel, weil hier genau ein Wert von den angegebenen Alternativen im Instanzdokument verwendet sein muss. Dies ist eine Alternative zu der enumeration-Fassette, wie sie bisher verwendet wurde.
120
2. Datentypen und Strukturen
2. 3. 2. 2 Bereiche Um einen Bereich anzugeben, verwendet man die eckigen Klammern und Zahlen oder Buchstaben für die beiden Bereichsgrenzen, getrennt von einem Bindestrich. Folgender Datentyp erlaubt alle Buchstaben (und nur Buchstaben) in seinem Wert, wobei genau ein Buchstabe möglich ist. Dies liegt daran, weil keine Häufigkeitsangabe gemacht wurde.
2. 3. 2. 3 Häufigkeiten Häufigkeiten lassen sich zum einen mit den folgenden Meta-Zeichen angeben: ●●
Plus (1 oder mehr)
●●
Fragezeichen (0 oder 1)
●●
Sternchen (0 oder mehr)
Fehlt eine entsprechende Angabe, handelt es sich um die Häufigkeit mit dem Wert 1. Für anspruchsvollere Häufigkeiten verwendet man eine Syntax aus geschweiften Klammern mit folgenden Eigenschaften: ●●
{n} – tritt n-Mal auf
●●
{n,m} – tritt genau n- bis genau m-Mal auf (also in Grenzen eingeschlossen)
●●
{n, } – tritt n-Mal oder mehr auf
Die folgende Tarifnummer tritt genau als zweistellige Zahl aus dem Bereich 0 bis 9 auf.
121
2
2. Datentypen und Strukturen
2
Der folgende Tarifname setzt sich aus einem Wort zusammen, alternativ gefolgt von einer 1 oder einer 2.
2. 3. 3. Kurzschreibweisen Für einige häufige oder besonders wichtige Eigenschaften von Zeichenketten gibt es Kurzschreibweisen, die zum einen von Perl und zum anderen von Unicode her bekannt sind bzw. auf Perl-Syntax und Unicode-Definitionen beruhen.
2. 3. 3. 1 Perl-Zeichenklassen Die Perl-Zeichenklassen erlauben es, spezielle Zeichen zu definieren, deren Beschreibung in der folgenden Tabelle angegeben ist. Wichtig ist dabei, auch entsprechende Häufigkeiten anzugeben, wenn solche Zeichen verwendet werden sollen, da sie nur jeweils ein Zeichen (also Menge 1) abbilden. Das Entwertungszeichen gehört immer zum Zeichen dazu, da ansonsten ja der entsprechende Buchstabe gemeint wäre.
Zeichen
Beschreibung
. \s \S \i
Jedes Zeichen außer neue Zeile und Absatz Leerzeichen (Leerzeichen, Absatz, Tabulator, neue Zeile) Alle Zeichen außer Leerezeichen, die von \s gefunden werden Der erste Buchstabe in einem XML-Identifizierer (Buchstabe, Unterstrich, Doppelpunkt) Alle Zeichen außer denen, die durch \i gefunden werden Alle Zeichen, die in einem XML-Namen auftauchen können (Anfangszeichen, Zahlen, Punkt, Unterstrich, Doppelpunkt) Alle Zeichen außer denen, die von \c gefunden werden
\I \c \C
122
2. Datentypen und Strukturen
Zeichen
Beschreibung
\d \D \w
Zahlen Alle Zeichen außer denen, die von \d gefunden werden Alle Zeichen, die in einem Word erscheinen können, d. h., ohne Interpunktion, Trennzeichen und sonstige Alle Zeichen außer denen, die von \W gefunden werden
\W
2
Tabelle 2.2: Perl-Zeichenklassen
Folgender Datentyp akzeptiert nur Tarifnamen, die aus Buchstaben, alternativ gefolgt von einer Zahl, bestehen. Leerzeichen sind nicht erlaubt.
Folgender Datentyp akzeptiert nur Tarifnamen, die aus Buchstaben und Zahlen bestehen, aber keine Leerzeichen enthalten.
Folgender Datentyp akzeptiert nur Tarifnamen, die aus Buchstaben und Zahlen bestehen, aber keine Leerzeichen enthalten. Die Länge der gesamten Zeichenkette liegt zwischen 1 und 20, er wird demnach in Grenzen eingeschlossen.
123
2. Datentypen und Strukturen
2
2. 3. 3. 2 Unicode-Zeichenklassen Ähnliche, wenngleich auch wesentlich umfangreichere Kurzschreibweisen liefern die folgenden Zeichenklassen, die auf Unicode-Definitionen beruhen. In der Referenz findet man sie noch einmal unterschiedlichen Kategorien zugeordnet wieder.
Eigenschaft
Bedeutung
L Lu Ll Lt
Alle Buchstaben Großbuchstaben Kleinbuchstaben Großschreibung von Substantiven auch in Sprachen, die diese Orthographie nicht kennen Ändernde Zeichen wie Akzente Sonstige Alle Marken Marken, die keinen Platz beanspruchen Marken, die mit einem anderen Zeichen kombiniert werden (wie Akzente) Marken, die ein anderes Zeichen einschließen (wie Kreise) Alle Zahlen Dezimal-Ziffern Buchstaben Sonstige Alle Satzzeichen Verbinder (wie Unterstrich) Gedankenstrich Öffnendes Zeichen (wie Klammer) Schließendes Zeichen Öffnendes Anführungszeichen (ähnlich Ps oder Pe) Schließendes Anführungszeichen (ähnlich Ps oder Pe) Sonstige Alle Trennzeichen Leerzeichen Zeilenvorschub Absatz Alle Symbole mathematische Symbole Währungssymbole
Lm Lo M Mn Mc Me N Nd Nl No P Pc Pd Ps Pe Pi Pf Po Z Zs Zl Zp S Sm Sc
124
2. Datentypen und Strukturen
Eigenschaft
Bedeutung
Sk So C Cc Cf Co Cn
Ändernde Zeichen Sonstige Alle anderen Kontrollzeichen Formatierung Reserviert Nicht verwendet
2
Tabelle 2.3: Unicode-Zeichenklassen
Speziell für Zeichen aus unterschiedlichen Sprachen bzw. Alphabeten, wobei auch figürliche Zeichen und Sonderzeichen (also keine Buchstaben) gemeint sind, bieten die folgenden Blocknamen des Unicode-Zeichensatzes. Sie entsprechen jeweils einem Block-Bereich im Unicode-Standard, wobei in den regulären Ausdrücken allerdings der Bereichsname, und nicht Beginn- und Endnummer zu verwenden ist. • • • • • • • • • • • • • • • • • • • • • • • • •
ControlPictures EnclosedAlphanumerics BlockElements MiscellaneousSymbols BraillePatterns KangxiRadicals CJKSymbolsandPunctuation Katakana HangulCompatibilityJamo BopomofoExtended CJKCompatibility CJKUnifiedIdeographs YiRadicals HighSurrogates LowSurrogates CJKCompatibilityIdeographs ArabicPresentationForms-A CJKCompatibilityForms ArabicPresentationForms-B HalfwidthandFullwidthForms OldItalic Deseret MusicalSymbols CJKUnifiedIdeographsExtensionB Tags
• • • • • • • • • • • • • • • • • • • • •
OpticalCharacterRecognition BoxDrawing GeometricShapes Dingbats CJKRadicalsSupplement IdeographicDescriptionCharacters Hiragana Bopomofo Kanbun EnclosedCJKLettersandMonths CJKUnifiedIdeographsExtensionA YiSyllables HangulSyllables HighPrivateUseSurrogates AlphabeticPresentationForms CombiningHalfMarks SmallFormVariants Gothic ByzantineMusicalSymbols MathematicalAlphanumericSymbols CJKCompatibilityIdeographsSupplement
Tabelle 2.4: Unicode-Zeichenklassen
125
2. Datentypen und Strukturen
2
Diese Zeichenklassen verwendet man mit den folgenden beiden Syntaxformen: ●●
\p{IsNAME} findet alle Zeichen des angegebenen Blocks.
●●
\P{IsNAME} findet alle Zeichen, die gerade nicht im angegebenen Block liegen.
Folgender Datentyp validiert nur solche Werte als gültig, die aus dem BaisLatin-Zeichensatz stammen und eine Länge zwischen 1 und 20 haben, die Grenze mit eingeschlossen.
2. 3. 4. Mengenverarbeitung Für die Mengendefinition stehen in den regulären Ausdrücken unterschiedliche Zeichen zur Verfügung. ●●
^ - Mit dem Zirkumflex lassen sich Mengen negieren, d. h., in ihren gefundenen Wer-
ten umkehren. Es steht immer am Anfang einer Gruppe und verliert die negierende Fähigkeit innerhalb einer Zeichenkette. ●●
- - Mit dem Minus-Zeichen lassen sich Mengen voneinander abziehen, sodass der Ausdruck [menge1-[menge2]] dazu führt, dass nur noch die Werte gefunden werden, die
in menge2, aber nicht in menge1 enthalten sind. ●●
126
[] – Mit den rechteckigen Klammern verknüpft man eine Menge bestehend aus einzelnen Atomen, die zwischen den eckigen Klammern zu finden sind.
Komplexe Typen und Inhaltsmodelle
3. Komplexe Typen und Inhaltsmodelle
3. Komplexe Typen und Inhaltsmodelle 3 3. 1. Deklaration von komplexen Typen In den zurückliegenden Beispielen tauchte bereits das Element complexType auf, dem in diesem Kapitel die gesamte Aufmerksamkeit gilt. Es bietet zwei Deklarationsmöglichkeiten, von denen die erste bereits in vorherigen Beispielen zum Einsatz kam: ●●
Lokale Deklaration: Für die Angabe von Inhaltsmodellen, die über die Angabe eines einfachen Datentyps hinausgehen, dienen die komplexen Typen als Container-Element für weitere Informationseinheiten (also sowohl für Attribute als auch für Elemente). In diesem Sinne benutzt man also complexType für die die Angabe von Inhaltsmodellen, die aus Elementen und Attributen bestehen.
●●
Globale Deklaration: Die gerade für die lokale Deklaration beschriebenen Inhaltsmodelle lassen sich auch global deklarieren und dann wie ein Datentyp einem deklarierten Element zuweisen. Dadurch eröffnet sich die Möglichkeit, inhaltliche Strukturen auszulagern, durch Vererbung zu erweitern und zu beschränken und damit die Vorteile von globalen Deklarationen nicht nur für einfache Datentypen, sondern auch für komplexe Inhaltsmodelle zu nutzen.
3. 1. 1. Lokale komplexe Typen Da bisher schon Inhaltsmodelle mit Kind-Elementen und Attributen auftraten, dürfte die grundsätzliche Verwendung der Schema-Komponente complexType bereits bekannt sein. In diesem Abschnitt soll sie nun vollständig mit ihren verschiedenen Varianten eingeführt und betrachtet werden.
128
3. Komplexe Typen und Inhaltsmodelle
3. 1. 1. 1 Einsatz von complexType Bei der Diskussion über die Prinzipien der Dokumentmodellierung ergab sich als fundamentale Technik, dass man für jedes Element sein Inhaltsmodell so definiert, dass die jeweils nächste Stufe betrachtet wird. Dieses wird auch als „Matrjoschka-Struktur“ oder „-Modellierung“ bezeichnet, weil die einzelnen Elemente in Stufenform bzw. wie in Zwiebelschalen in mehreren, übereinander liegenden Ebenen deklariert werden. Dabei handelt es sich um eine sehr effiziente Vorgehensweise, weil man über die einzelnen Äste des Dokumentbaums alle Elemente der Reihe nach bzw. auf jeder Ebene deklariert. Natürlich ist dies nicht die einzige Methode, Inhaltsmodelle anzugeben, aber es ist die einfachste. Sie basiert auf der Vorgehensweise der Document Type Definition und wird auch bei den anderen Möglichkeiten, die XML Schema anbietet, als Grundbaustein verwendet. Die XML Schema-Komponente complexType kommt demnach für die folgenden Inhaltsmodelle in Frage, wobei natürlich beide auch in Kombination auftreten können: ●●
Verwendung von Elementen: Das zu deklarierende Element ist selbst Eltern-Element von anderen Elementen, die ihrerseits entweder einen Textknoten enthalten oder auch Eltern-Element von anderen Elementen sein können.
●●
Verwendung von Attributen: Das zu deklarierende Element enthält Attribute zu genaueren Beschreibung seines Zustandes oder seines Inhalts.
●●
Gemischter Inhalt: Das zu deklarierende Element enthält neben weiteren Elementen und/oder Attributen auch direkten Inhalt.
Als Beispiel soll für die einfachste Verwendung von complexType folgendes XML-Dokument dienen, das eine Kundenaufstellung enthält, die nur aus sehr wenigen Elementen besteht. Für jedes Element Stadt speichert man in zwei untergeordneten Elementen den Namen in einem Element Name und die Anzahl in einem weiteren Element namens Kunden. Für das Wurzelelement Kundenuebersicht sind zusätzlich zwei Attribute vorhanden, die das aktuelle Datum der Übersicht sowie den Typ der betrachteten Kunden enthalten. Dortmund 64
129
3
3. Komplexe Typen und Inhaltsmodelle
Düsseldorf 62
3
31_01.xml: Kundenübersicht
In Abbildung 3.1 erkennt man, dass zwei Eltern-Elemente vorliegen, von denen das eine das Wurzelelement ist. Für das einzige untergeordnete Element gilt wiederum, dass es ein Eltern-Element von zwei untergeordneten Elementen ist, die allerdings schließlich nur reinen Textinhalt enthalten.
Abbildung 3.1: Kundenübersicht
Mit der Syntax der herkömmlichen DTD definiert man Eltern-Elemente innerhalb der runden Klammern, die das Inhaltsmodell beschreiben, durch den Aufruf der untergeordneten Elemente. Damit gibt man an, welche Elemente auf der nächsten untergeordneten Stufe im Dokumentbaum angesiedelt sind. Für die Angabe von direktem Inhalt verwendet man keine Datentypen, aber das Schlüsselwort PCDATA . Für die derart gekennzeichneten Inhaltsmodelle gilt, dass die zugehörigen Elemente die Blätter und damit das Ende eines Zweiges im Dokumentbaum darstellen. Sie beenden damit einen möglichen Pfad über einen oder mehrere Äste in einem Dokumentbaum. Man weist zusätzlich einem Element seine Attribute zu, indem über das Schlüsselwort ATTLIST der Elementname aufgerufen wird, der die angegebenen Attribute enthalten soll. Diese Angabe integriert die DTD-Syntax also gerade nicht in die runden Klammern, die das Inhaltsmodell beschreiben, obwohl sie natürlich ebenfalls Inhalt eines Elements repräsentieren. Mit der reinen Namensnennung der untergeordneten Elemente gibt man an, welche Elemente innerhalb des Eltern-Elements aufgerufen werden können. Dies regelt die Existenz der Kind-Elemente. Über spezielle Zeichen wie z. B. das Plus-Zeichen oder das Fragezeichen steuert man die Häufigkeit (Kardinalität) jedes dieser Kind-Elemente individuell, während
130
3. Komplexe Typen und Inhaltsmodelle
man über das Komma und weitere Klammern eine Angabe über die Reihenfolge angibt, wobei zusätzliche Klammern Gruppen innerhalb des Inhaltsmodells bilden.
3
31_01.dtd: Angabe von Eltern-Elementen in einer DTD
Die für die DTD-Syntax gerade noch einmal erwähnten Angaben zu Existenz, Reihenfolge und Kardinalität lassen sich natürlich auch in XML Schema angeben, allerdings in einer völlig anderen Syntax. Zunächst einmal deklariert man jedes Element, das selbst untergeordnete Elemente enthält, gerade nicht als leeres Element wie z. B. , sondern als Container, dessen erste Angabe das Element complexType darstellt. Dies gilt im Standardfall ganz pauschal für das Wurzelelement, das in den meisten Fällen nur aus Kind-Elementen besteht. Innerhalb dieses Containers wiederum platziert man nun die Angabe von Elementen genauso wie die von Attributen. Für das Element Kundenuebersicht sieht man in der nachfolgenden kompletten Angabe der Schema-Datei, dass sein Inhalt auf der nächsten untergeordneten Ebene ausschließlich aus beliebig vielen Vorkommen des Elements Stadt sowie den beiden Attributen Typ und Kunden besteht. Dabei regeln die optionalen Attribute minOccurs und maxOccurs ja gerade die Häufigkeit mit einer konkreten Zahlenangabe, dem festen Wert unbounded für unbegrenzte Häufigkeit oder dem Standardwert 1 bei Nicht-Angabe des gesamten Attributs. Das als Matrjoschka-Design bekannte Modellierungsverfahren tritt beim XML Schema deutlich hervor, da für die gerade deklarierten Kind-Elemente wiederum die untergeordneten Kind-Elemente deklariert werden und sich dieses verschachtelte Vorgehen so lange fortsetzt, bis man für den jeweiligen Ast im Dokumentbaum das letzte Blatt erhält. Dieses enthält in den meisten Fällen Textinhalt, der dann über eine Angabe eines Datentyps mit einem bestimmten Wertebereich verknüpft wird. Allerdings besteht das Inhaltsmodell wie im Falle des Wurzelelements nicht ausschließlich aus complexType und einer Liste der untergeordneten Elemente, sondern auch noch aus
131
3. Komplexe Typen und Inhaltsmodelle
einem weiteren Element, nämlich dem Element sequence. Dabei ergibt sich die folgende Struktur:
3
Elementliste
Attributliste
Die Attributliste liegt außerhalb eines weiteren Containers, bzw. – andersherum betrachtet – die Elemente selbst werden von diesem weiteren Container umschlossen. Bisher handelte es sich dabei stets um die Schema-Komponente sequence. Dies ist allerdings kein Standardfall, sondern nur der am häufigsten anzutreffende, da in den meisten Fällen auch eine Angabe über die Reihenfolge der Elemente gemacht werden muss. Mit diesem Element signalisiert man, dass die nun folgenden deklarierten Elemente genau in der deklarierten Reihenfolge im Instanzdokument auftreten müssen. Weitere Definitionsmöglichkeiten wie z. B. eine Auswahl oder eine beliebige Reihenfolge folgen im Verlauf dieses Kapitels. Da die Attribute von der Element-Reihenfolge unbeeinflusst bleiben, liegen sie verständlicherweise außerhalb dieses zusätzlichen Containers. Komplett ergibt sich damit folgendes XML Schema-Dokument:
132
3. Komplexe Typen und Inhaltsmodelle
3
31_01.xsd: Verwendung von complexType
Abbildung 3.2 soll noch einmal das Matrjoschka-Vorgehen und die Aufteilung der Inhalte von complexType verdeutlichen. Die Elemente werden sukzessive entlang der Äste im Dokumentbaum deklariert, wodurch eine derartige Verschachtelung innerhalb der Syntax entsteht, die an eine Matrjoschka erinnert. Hinzu kommt, dass zunächst die Elemente innerhalb eines entsprechenden Containers, der die Reihenfolge oder die Auswahl der Elemente enthält, und dann die Attribute außerhalb des gerade erwähnten Containers deklariert werden.
Abbildung 3.2: Matrjoschka-Prinzip und Inhalte von complexType
Die Verschachtelung der Syntax bzw. insbesondere das Matrjoschka-Design lässt sich auch sehr gut in einem XML Schema-Editor wie z. B. dem XMLSpy von Altova nachvollziehen. In Abbildung 3.3 erkennt man in der so genannten „Grid View“ sehr deutlich, wie die einzelnen Elemente wiederum andere Elemente enthalten.
133
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.3: Darstellung des Matrjoschka-Designs im XMLSpy
3. 1. 2. Einfaches Inhaltsmodell Das Einführungsbeispiel sollte die grundsätzliche Verwendung der Schema-Komponente complexType erläutern und einen Bogen spannen, welche unterschiedlichen weiteren Komponenten noch notwendig sind, um die aus der DTD her bekannten Strukturen mindestens abzubilden. Ein sehr einfaches Inhaltsmodell, für das auch nur ein sehr kurzes XMLDokument als Beispiel dienen kann, besteht aus der häufig anzutreffenden Kombination von Attribut und direktem Inhalt. Wie man nachfolgend erkennt, speichert das Wurzelelement Kundenuebersicht erneut beliebige viele Stadt-Elemente. Diese allerdings enthalten lediglich den Stadtnamen als Textinhalt, während die Anzahl der Kundenunternehmen in diesem Ort in einem Attribut Kunden vorliegt. Dortmund Düsseldorf
134
3. Komplexe Typen und Inhaltsmodelle
Essen, Ruhr 31_02.xml: Verwendung von Attributen bei Elementen mit einfachem Inhalt
Für das Wurzelement ändert sich strukturell nichts, da auf dieser Ebene im Dokumentbaum tatsächlich keine Änderungen gegenüber dem Einführungsbeispiel auftraten. Für das Element Stadt hingegen benötigt man nun für die Abbildung des reinen Textinhalts und der gleichzeitigen Verwendung des Attributs einen speziellen Container. Das Element simpleContent ermöglicht dagegen, als Inhaltsmodell und des speziellen Containers extension diese Kombination zu modellieren. Die Schema-Komponente extension dient dazu, einen Datentyp für den Textinhalt abzuleiten, der in diesem Fall eine einfache Zeichenkette darstellt. Einschränkungen über Fassetten sind nun nicht mehr möglich, da hierfür die Schema-Komponente restriction notwendig wäre. Über extension ruft man nur im type-Attribut den Datentyp auf, der für den direkten Textinhalt gelten soll.
135
3
3. Komplexe Typen und Inhaltsmodelle
31_02.xsd: Einfaches Inhaltsmodell mit Attribut
3
3. 1. 2. 1 Ableitung von einfachem Inhalt
Abbildung 3.4: Ableitungstechniken für einfachen Inhalt
Die gerade vorgestellten Schema-Komponenten treten noch in einem weiteren Zusammenhang auf, der mit Hilfe der beiden Ableitungstechniken für einfachen Inhalt und globalen komplexen Typen realisiert werden kann. Ausgehend von einem globalen komplexen Typ, der sich durch eine Platzierung außerhalb jeglicher anderer Deklarationen bzw. direkt unterhalb des schema-Elements auszeichnet und einen Namen besitzt, lassen sich seine Eigenschaften nicht nur anderen Elementen zuweisen (siehe hierzu auch den nächsten Abschnitt), sondern auch in Grenzen verändern. Voraussetzung für eine Ableitung in dem hier diskutierten Fall des einfachen Inhalts im type-Attribut der lokalen Deklaration aufgerufenen globalen komplexen Typen ist, dass nur folgende Veränderungen vorgenommen werden: ●●
136
Ableitung durch Erweiterung: Hinzufügen eines lokal deklarierten Attributs. Datentypen können nicht geändert werden.
3. Komplexe Typen und Inhaltsmodelle
●●
Ableitung durch Einschränkung: Verzicht auf ein global deklariertes Attribut durch lokales Verbot oder Einschränkung des Wertebereichs durch für den im globalen komplexen Typ gültige Fassetten. Datentypen können nicht geändert werden.
ÄÄ Ableitung durch Erweiterung Mit der Ableitung durch Erweiterung bezieht man sich auf einen globalen komplexen Typ, der nur ein einfaches Inhaltsmodell bzw. syntaktisch den Container simpleContent enthält. Auf dieses greift man – im Übrigen wie bei allen anderen globalen komplexen Typen des nächsten Abschnitts auch – im type-Attribut des element-Elements zu und erweitert es um Attribute. Es ist nicht möglich, den Datentyp zu verändern oder gar Elemente einzufügen, denn dies würde ja nicht mehr dem ursprünglich global deklarierten einfachen Inhaltsmodell entsprechen. Diese Ableitungstechnik dient tatsächlich nur dazu, Attribute nachträglich für Elemente vorzugeben und den ursprünglich vorhandenen komplexen Typ mit Hilfe dieser neuen Attribute zu erweitern. Bezogen auf das ursprüngliche XML-Dokument erstellt man über die bereits bekannte Schema-Komponente complexType einen mit Hilfe des name-Attributs benannten komplexen Typ. Er enthält ein mit simpleContent beschriebenes einfaches Inhaltsmodell, bestehend aus direktem Textinhalt als Zeichenkette und ein optionales Attribut Wachstum, das mit einer kurzen Bewertung ohne Leerzeichen die Kundenentwicklung klassifizieren kann. Für das Element Stadt ruft man, wie es bei einfachen und komplexen Typen üblich ist, den globalen komplexen Typ über seinen qualifizierten Namen auf und überträgt die Eigenschaften des globalen Typs in die lokale Deklaration. Da aber der vorhandene Typ nur ein Basistyp sein soll, weil man ja weitere Attribute einfügen möchte, verwendet man nicht etwa die Syntax , sondern erstellt mit complexType und simpleContent wiederum zwei Container für die Ableitung durch Erweiterung. Im Attribut base der Schema-Komponente extension wird nun auf den vorhandenen globalen komplexen Typ verwiesen und dann innerhalb dieses Containers die Erweiterung in Form eines Attributs namens Kommentar deklariert. Dieses soll, wie der Name schon sagt, Kommentare in Zeichenkettenform für eine weitere Bewertung der vom Element erfassten Stadt enthalten.
137
3
3. Komplexe Typen und Inhaltsmodelle
31_03.xsd: Ableitung durch Erweiterung
Abbildung 3.5 fasst die beiden entscheidenden Bereiche der Ableitung durch Erweiterung noch einmal schematisch zusammen. Der globale komplexe Typ liegt außerhalb der Deklaration des Wurzelelements und enthält die Angabe eines Datentyps für den direkt gespeicherten Inhalt sowie das optionale Attribut. Später verweist man auf diesen globalen Typ und ergänzt ihn um genau ein zusätzliches Attribut.
138
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.5: Verwendung eines globalen komplexen Typs unter Ableitung durch Erweiterung
ÄÄ Ableitung durch Einschränkung Die zweite Ableitungstechnik dient dazu, globale komplexe Typen bei der lokalen Deklaration von Elementen, die sich auf sie beziehen, weiter einzuschränken. Dies beschränkt sich selbst allerdings wiederum auf Fassetten, die für den global definierten komplexen Typ gültig sind, oder auf die Veränderung von Attributverwendungen wie von required nach optional/prohibited oder von optional nach prohibited. Ausgehend von einem ähnlichen globalen komplexen Typ wie im vorherigen Abschnitt – mit dem einzigen Unterschied, dass die beiden Attribute Kommentar und Wachstum schon vorhanden sind – beschränkt man in der lokalen Deklaration den Wertebereich und die Attributverwendung. Da der Basisdatentyp string ist, lässt sich als lokale Beschränkung die Zeichenkettenlänge auf ein Intervall von 1 bis 30 begrenzen. Da das Attribut Kommentar global mit der Verwendungseigenschaft optional definiert wurde, lässt sich dies mit prohibited ebenfalls beschränken. Wäre die Verwendung required gewesen, dann hätte eine Beschränkung mit optional eingerichtet werden können.
139
3. Komplexe Typen und Inhaltsmodelle
31_04.xsd: Ableitung durch Einschränkung
140
3. Komplexe Typen und Inhaltsmodelle
Abbildung 3.6 kennzeichnet noch einmal schematisch die Definition des globalen komplexen Typs und die Deklaration des auf ihn bezogenen lokalen Elements Stadt. Innerhalb des einfachen Inhalts lassen sich dann ein Attribut in seiner Verwendung und der Wertebereich des gesamten Textinhalts über an dieser Stelle gültige Fassetten beschränken.
3
Abbildung 3.6: Verwendung eines globalen komplexen Typs unter Ableitung durch Einschränkung
3. 1. 3. Globale komplexe Typen Bei der Diskussion des einfachen Inhalts tauchten bereits globale komplexe Typen1 auf. Sie unterscheiden sich von ihrem syntaktisch ähnlich erscheinenden Pendant dadurch, dass sie direkt ein Kind-Element des schema-Elements sind und einen Namen tragen. In diesem Abschnitt soll die Funktionsweise noch einmal deutlich hervorgehoben werden, wobei es gerade nicht um einfachen, sondern um komplexen Inhalt geht. Einen solchen definiert man zwar nicht über ein dem simpleContent nachempfundenes Element in der Form complexContent, sondern über eine genauere Beschreibung, wie die untergeordneten 1
Vgl.: http://www.w3.org/TR/xmlschema-1/#Complex_Type_Definitions
141
3. Komplexe Typen und Inhaltsmodelle
Elemente auftreten sollen. Die Verwendung des tatsächlich existierenden Elements complexContent ist für die Ableitung von globalen komplexen Typen reserviert. 3. 1. 3. 1 Einfache Verwendung
3
Globale komplexe Typen eignen sich dazu, wieder verwendbare Komponenten in Form von benannten Bereichen als Kind-Elemente des schema-Elements zu erstellen, die später innerhalb der Definitionen anderer Elemente in ihrem type-Attribut aufgerufen werden. Dies bildet eine Schnittstelle zu den Datentypen, verhält sich allerdings ganz anders als diese. Ähnlich ist nur, dass auch hier über die Inhalte des jeweiligen Elements Aussagen getroffen werden, die allerdings nicht direkt lokal vorgegeben werden, sondern gerade über einen bereits vorhandenen qualifizierten Namen mit dem speziellen Element in Zusammenhang gebracht werden. Man überträgt dadurch die im globalen komplexen Typ definierten Eigenschaften in das gerade deklarierte Element und verzichtet dabei auf eine lokale Definition der jeweiligen Kind-Elemente. Folgendes Dokument enthält eine Umsatzübersicht für die Stadt Essen im Verlauf mehrerer Monate. Dabei unterscheidet man einen Gesamt- und einen ProKopf-Umsatz, wobei in beiden Fällen die Elemente Umsatz und Anrufe verwendet werden. Durch ihre ElternElemente allerdings klärt sich, dass die jeweiligen Zahlen entweder Gesamt oder ProKopf der Kunden in der bestimmten Stadt zu sehen sind. Die Anzahl der Kunden ist zusätzlich in einem Kunden-Element innerhalb von Gesamt angegeben. 7154.01 200 18869 35.77 94.35
142
3. Komplexe Typen und Inhaltsmodelle
7581.35 213
19887
3
35.59
93.37
31_05.xml: Umsatzübersicht mit untergeordneten, gleichen Elementen
Abbildung 3.7: Elementstruktur der Erfolgsübersicht
Bei der Definition von globalen komplexen Typen setzt man das Element complexType in Verbindung mit seinem name-Attribut ein, das als Wert einen eindeutigen Namen erhält. Die Angabe des Inhaltsmodells erfolgt dann über die in einem späteren Abschnitt erklärten Techniken. Für den Augenblick ist dies noch immer die Angabe von mehreren Kind-Elementen, die über das Element sequence in eine definierte Reihenfolge gebracht werden. Im konkreten Fall ergibt sich z. B. für die Angabe des Gesamtumsatzes folgender komplexer Typ:
143
3. Komplexe Typen und Inhaltsmodelle
Definition eines globalen komplexen Typs
3
Bei der Verwendung des gerade definierten globalen komplexen Typs ruft man den qualifizierten Namen im type-Attribut des Elements auf, das die Eigenschaften des Typs übernehmen soll. Für das Beispieldokument ist dies das Element Gesamt: Verwendung eines globalen komplexen Typs
In folgendem Quelltext befindet sich das gesamte Schema-Dokument mit den Regeln für die Erfolgsübersicht nach Städten. Man definiert zwei globale komplexe Typen für die Umsatzangaben Gesamt und ProKopf sowie zusätzlich einen so genannten ErfolgTyp, der den eigentlichen Dokumentinhalt noch einmal gesondert auslagert und innerhalb eines globalen komplexen Typs auf andere solche Typen zurückgreift. Da darüber hinaus die Elemente Umsatz und Anrufe wiederholt im Dokument auftauchen, lohnt es nicht, sie lokal für jeden Typ zu deklarieren. Stattdessen greift man hier wieder auf globale Elemente zurück, die dann in den einzelnen Typen zum Einsatz kommen.
144
3. Komplexe Typen und Inhaltsmodelle
3
31_05.xsd: Verwendung von globalen komplexen Typen
In Abbildung 3.8 erkennt man, dass insgesamt drei verschiedene globale komplexe Typen zum Einsatz kommen, von denen einer die beiden anderen wiederum enthält. Innerhalb dieser Typen verweist man auf globale Elemente, die teilweise wiederholt auftreten.
145
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.8: Übersicht der Elemente und Typen
Die schematische Abbildung macht die Verschränkung der einzelnen ausgelagerten Komponenten des Schema-Dokuments noch ein wenig deutlicher. Während die globalen Elemente Umsatz, Anrufe und Kunden innerhalb der beiden globalen komplexen Typen ProKopfTyp und GesamtTyp aufgerufen werden, referenziert diese beiden Typen der ebenfalls globale komplexe Typ ErfolgTyp innerhalb seiner beiden Kind-Elemente Gesamt und ProKopf. Er beinhaltet zusätzlich auch die beiden Attribute Stadt und Monat und wird dann später im type-Attribut des einzigen Kind-Elements Erfolg des Wurzelelements aufgerufen.
146
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.9: Globale komplexe Typen und Elemente
3. 1. 3. 2 Verwendung und Ableitung Das vorherige Beispiel sollte hauptsächlich die grundsätzliche Verwendung von globalen komplexen Typen und die dafür notwendige Syntax erklären. Wie schon bei den einfachen Inhalten, die ebenfalls global deklariert werden konnten, besteht auch hier die Möglichkeit, sich über Ableitungen mehr Flexibilität zu verschaffen. Dabei handelt es sich auch in diesem Fall um die beiden folgenden Ableitungstechniken: ●●
Ableitung durch Erweiterung: Der globale komplexe Typ dient als Basis für eine Erweiterung um Elemente und Attribute in Form einer Reihenfolge, die zunächst aus den Elementen und Attributen besteht, die schon im Inhaltsmodell des globalen komplexen Typs vorhanden sind. Diese Reihenfolge wird dann ergänzt um die neuen Elemente und Attribute. Wichtig ist hier, dass die Reihenfolge der Elemente im globalen
147
3. Komplexe Typen und Inhaltsmodelle
komplexen Typ nicht verändert werden kann. Es handelt sich um ein Anhängen von neuen Strukturen. ●●
3
Ableitung durch Einschränkung: Der globale komplexe Typ dient als Basis für eine Einschränkung um Elemente und Attribute, wobei keine syntaktische oder inhaltliche Gemeinsamkeit mit den anderen Ableitungstechniken besteht. Zwar verringert sich durch die Einschränkung die Anzahl und Auswahl der Elemente und Attribute, doch muss dabei das komplette neue Inhaltsmodell definiert werden. Es besteht über den Aufruf des globalen komplexen Typen im type-Attribut des Elements lediglich ein Hinweis, dass eine übergeordnete, ähnliche Struktur vorhanden ist.
Abbildung 3.10: Ableitungstechniken für komplexe Typen
ÄÄ Ableitung durch Erweiterung Bei der Ableitung durch Erweiterung ergänzt man einen gegebenen globalen komplexen Typen um weitere Elemente oder Attribute. Wichtig ist hier die Einschränkung, dass man also keine andere Reihenfolge wählen und nur weitere Elemente an die ohnehin schon bestehenden des globalen komplexen Typen anhängen kann. Das gleiche Prinzip gilt auch für Attribute. Daher ist bei der Gestaltung des XML-Dokuments Vorsicht geboten, damit eine mögliche Ableitung und dadurch z. B. eine weitere Auslagerung von Komponenten oder eine Verkürzung von Quelltext überhaupt realisierbar wird.
148
3. Komplexe Typen und Inhaltsmodelle
Für das aktuelle Beispiel bedeutet dies, dass man die Reihenfolge der Elemente Umsatz, Kunden, Anrufe im Eltern-Element Gesamt der Reihenfolge im Element ProKopf an Umsatz, Anrufe angleichen muss. Dadurch hat man die Möglichkeit, einen einzigen UmsatzTyp zu definieren, der dann für das Element Gesamt um genau das Element Kunden erweitert werden kann. Das Instanzdokument verändert sich also auf folgende Weise:
3
7154.01 18869 200
35.77 94.35 31_06.xml: Erfolgsübersicht mit veränderter Kind-Element-Reihenfolge
Den vormals vorhandenen globalen komplexen Typ ProKopfTyp löscht man komplett und ändert den Typ GesamtTyp in einen UmsatzTyp, der aus den beiden Elementen Umsatz und Anrufe als Kind-Elemente besteht. Beim Anruf im Element ProKopf lässt sich ganz einfach im type-Attribut der gerade definierte Typ aufrufen, da das Inhaltsmodell von ProKopf exakt mit dem des Typs UmsatzTyp übereinstimmt. Für das Element Gesamt hingegen deklariert man das noch fehlende Element Kunden, indem man über den Container extension mit dem Basistypaufruf UmsatzTyp und dem Container sequence das noch benötigte weitere Element an die bereits vorhandenen Elemente anfügt.
149
3. Komplexe Typen und Inhaltsmodelle
3
... 31_06.xsd: Ableitung durch Erweiterung
In Abbildung 3.11 erkennt man, dass der globale komplexe Typ UmsatzTyp für beide Elemente Gesamt und ProKopf als Basistyp dient. Im Fall von Gesamt jedoch schließt man an die Elemente, die im globalen komplexen Typ bereits deklariert wird, das noch benötigte Element Kunden an. Da es sich tatsächlich um ein Anhängen handelt, erhält man die gewünschte Reihenfolge.
150
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.11: Struktur bei Ableitung durch Erweiterung
Abbildung 3.12: Ableitung durch Erweiterung
In Abbildung 3.12 soll noch einmal die syntaktische Struktur der Ableitung durch Erweiterung schematisiert werden. Über den Container sequence lässt sich nach dem Aufrufen
151
3. Komplexe Typen und Inhaltsmodelle
des Basistyps im type-Attribut des zu deklarierenden Elements (in diesem Fall ja auch wiederum ein globaler komplexer Typ) das Element an die bereits vorhandenen anhängen.
3
ÄÄ Ableitung durch Einschränkung Die Ableitung durch Einschränkung fällt für globale komplexe Typen deutlich aus dem Rahmen der bisher vorgestellten Syntax und Konzeptionen. Zwar lässt sich ein Basistyp definieren, aber anstatt – wie bei einfachem Inhalt möglich – die nicht benötigten Elemente über minOccurs, maxOccurs oder Attribute über use auszuschalten bzw. in ihrer Häufigkeit oder Verwendung zu begrenzen, muss man das gesamte Inhaltsmodell definieren. Dabei verzichtet man dann auf die nicht benötigten Elemente. Grundsätzlich kommt dies aber einer komplett neuen Definition gleich, denn es gibt keine Syntax, um Elemente wegzulassen, sondern man muss diejenigen, die übrig bleiben, alle aufzählen. Das Beispiel des vorherigen Abschnitts bleibt weiterhin gültig, wenn auch nun die Perspektive für die Definition des globalen komplexen Typs eine andere ist. Anstatt ein Minimalinhaltsmodell für den Typ zu definieren, verwendet man nun eine Maximalform, indem alle drei möglichen Elemente deklariert werden. Dies erlaubt zwar nun eine komplette Übernahme des Typs für das Element Gesamt, zwingt allerdings zu einer Einschränkung für den Typ ProKopf. Diese Einschränkung gelingt über den schon bekannten Container restriction mit Aufruf des Basistyps UmsatzTyp und dem ebenfalls bekannten Container sequence, der die Elemente in eine Reihenfolge bringt. Hier nennt man nun das gesamte Inhaltsmodell für das Element ProKopf und verhindert über eine Nichtnennung, dass dieses Element innerhalb von ProKopf erscheint.
152
3. Komplexe Typen und Inhaltsmodelle
3
... 31_07.xsd: Ableitung durch Einschränkung
In Abbildung 3.13 erkennt man deutlich, dass bei der Ableitung durch Einschränkung im Grunde genommen gar keine Typableitung stattfindet, sondern eigentlich nur ein in der Syntax des type-Attributs verankerter Bezug zu einer wieder verwendbaren Komponente gelegt wird. Es handelt sich vielmehr um eine ganz gewöhnliche Element-Deklaration innerhalb eines globalen komplexen Typs, in dem auf zwei globale Elemente verwiesen wird.
153
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.13: Ableitung durch Einschränkung
Abbildung 3.14: Ableitung durch Einschränkung
Diese syntaktisch etwas unglückliche Konzeption der Ableitung durch Einschränkung bei globalen komplexen Typen zeigt noch einmal die schematisierte Syntax in Abbildung 3.14. Zwar ruft man im type-Attribut den benötigten Basistyp auf, aber in Wirklichkeit deklariert
154
3. Komplexe Typen und Inhaltsmodelle
man das entsprechende Element wie alle anderen Elemente auch, die sich gerade nicht auf einen globalen komplexen Typ beziehen.
3. 2. Inhaltsmodelle Mit einem Inhaltsmodell bezeichnet man die Angabe, welche Inhalte in einem Element zugelassen sind. Dies kann sich im einfachen Fall auf die Angabe eines Datentyps beschränken, der den Wertebereich von im Element gespeicherten direkten Inhalt beschreibt. Dies kann sich ebenfalls im einfachen Fall darauf beschränken, über das simpleContent-Element eine Ableitung von einem globalen komplexen Typen zu generieren und zusätzlich auch noch Attribute zu definieren. Im komplexen Fall mit Hilfe des complexContent-Elements beschreibt ein Inhaltsmodell vielmehr, welche Kind-Elemente in einem Element auftreten dürfen und in welcher Beziehung sie selbst untereinander stehen. Zu diesen Beziehungen fanden sich in den zurückliegenden Schema-Dokumenten immer nur Reihenfolgen, doch es gibt hier nicht nur andere Möglichkeiten, Inhalte über Elemente zu steuern, sondern überhaupt Inhalte zu definieren. Diese Neuheiten sollen zusammen mit den bereits an unterschiedlichen Stellen des Buchs verwendeten Techniken in Zusammenhang gebracht und dargestellt werden. Das Verständnis von Inhaltsmodellen in diesem Abschnitt basiert auf der herkömmlichen DTD und soll im Vergleich zu ihr die unterschiedlichen Varianten erläutern. Ihr Verständnis wird ein wenig dadurch erschwert, dass man zwischen den Elementen simpleContent, complexContent sowie complexType und – zumindest was den Namen angeht – auch simpleType unterscheiden muss. 3. 2. 1. Einfache Inhalte Ein einfaches Inhaltsmodell oder ein einfacher Inhalt, wie er in diesem Buch genannt wird, soll für die Verwendung von direktem Inhalt und für die Deklaration eines Attributs gelten. Direkter Inhalt stellt dabei einen Textknoten dar. Im Gegensatz also zu einem ElternElement, das wiederum andere Elemente enthält, handelt es sich bei einem direkten Inhalt nicht um einen Abschnitt auf einem Ast im Dokumentbaum, sondern genau um das Blatt, also das Ende eines Zweiges. Da hier Text gespeichert wird (zu leerem Inhalt später mehr), der über einen bestimmten vordefinierten oder benutzerdefinierten Datentyp bestimmt wird, handelt es sich um einen Textknoten, der bisher immer mit dem bildhaften Ausdruck als direkter Inhalt bezeichnet wurde.
155
3
3. Komplexe Typen und Inhaltsmodelle
3. 2. 1. 1 Direkter Inhalt und Textknoten
3
In folgendem Instanzdokument gibt es natürlich sowohl Eltern-Elemente als auch Kind-Elemente, doch sollen nur die Elemente in Betracht gezogen werden, die Textknoten enthalten. Damit sind Name und Stadt gemeint, wobei Name zusätzlich noch das Attribut Anrede enthält. Beide stellen für die Äste Mitarbeiterliste / Mitarbeiter / Name und Mitarbeiterliste / Mitarbeiter / Stadt die Blätter der Äste im Dokumentbaum dar und enthalten jeweils Textknoten, die z. B. in XPath alle gleichzeitig über //text() oder getrennt über //Name/text() oder //Stadt/text() auswählbar sind. Marcus Bodensee Marl, Westf Markus Feder Herne, Westf
32_01.xsd: Einfache Elemente mit und ohne Attribute
Abbildung 3.15: Mitarbeiterliste mit Textknoten
3. 2. 1. 2 Deklarationsmöglichkeiten Für die Modellierung solcher Inhaltsmodelle gibt es unterschiedliche Alternativen, die bereits an anderer Stelle und mit anderen Beispielen erläutert wurden, hier aber noch einmal aus dem Blickwinkel der Angabe von Inhaltsmodellen zusammengefasst werden sollen. Dabei ist also die Syntax der Element- und Attributdeklaration, der Ableitung, der Definition
156
3. Komplexe Typen und Inhaltsmodelle
von einfachen und komplexen Typen sowie ihr Aufruf nicht von Bedeutung, sondern nur die Aussage, die sie in Bezug auf den Inhalt eines Elements treffen.
ÄÄ Angabe eines Datentyps Im type-Attribut des element-Elements ruft man einen vordefinierten oder über simpleType global benutzerdefinierten Datentyp auf und weist dem Textknoten des Elements damit seinen zugehörigen Wertebereich zu. Attribute können in diesem Inhaltsmodell nicht auftreten, denn es handelt sich syntaktisch um ein leeres Element.
Alternativ lässt sich über simpleType und den Containern restriction, list und union ein eigener Datentyp konstruieren, der – ausgehend von einem Basistyp – über für diesen Typ gültige Fassetten bestimmt wird. 32_01.xsd: Verwendung eines vordefinierten oder eigenen Datentyps
Alternativ besteht dann noch die Möglichkeit, einen eigenen Datentyp global zu definieren und ihn einfach im type-Attribut des element-Elements aufzurufen. Weitere Einschränkungen entfallen hier, da die globalen Eigenschaften exakt übernommen werden sollen.
157
3
3. Komplexe Typen und Inhaltsmodelle
32_02.xsd: Verwendung eines globalen, einfachen Typs
3
ÄÄ Verwendung eines Attributs Soll ein Element neben einem Textknoten zusätzlich ein oder mehrere Attribute enthalten, handelt es sich um einen einfachen Inhalt, der über simpleContent deklariert wird und sowohl die Textknotendefinition als auch die Attributdeklaration umschließt. Dies muss wiederum im Container complexType angesiedelt werden, da man gleichzeitig einen Textknoten und ein Attribut angeben möchte. Die Zuordnung dieses Elements zu einfachem Inhalt erfolgt hier nur über die Existenz des Textknotens und der Tatsache, dass dieser Textknoten der Inhalt des Elements ist. Die Verwendung von complexType darf nicht mit dem Inhaltsmodell verwechselt werden, sondern ist nur syntaktisch verpflichtend, um Textknoten und Attribut anzuführen. Das einfache Inhaltsmodell drückt man über simpleContent und seinen Inhalt (Textknoten) aus. 32_02.xsd: Deklaration eines Attributs
Neben der Angabe, dass ein Attribut mit einem bestimmten Namen zu einem Element gehört, ist natürlich auch das Inhaltsmodell des Attributs selbst wichtig. Hierbei gibt es nur zwei Möglichkeiten. Sie ähneln den Inhaltsmodellen für Elemente, wenngleich hier auch einige Einschränkungen zu beachten sind:
158
3. Komplexe Typen und Inhaltsmodelle
●●
Angabe eines Datentyps: Wie bei jedem Element besteht die Möglichkeit, einen vordefinierten oder benutzerdefinierten Datentyp zu verwenden. Dieser kann entweder über seinen Namen im type-Attribut des attribute-Elements aufgerufen oder über simpleType und unter Angabe eines bereits vorhandenen Datentypen als Basistypen und den für diesen Typen möglichen Fassetten innerhalb der Attribut-Deklaration definiert werden. Vordefinierter oder eigener lokal definierter Datentyp:
Eigener lokal definierter Datentyp:
31_03.xsd: Lokale Definition eines eigenen Datentyps für ein Attribut
●●
Ableitung von einem global definierten Datentyp: Anstatt einen global vorhandenen Datenzypen einfach aufzurufen, kann man durch eine Ableitung durch Einschränkung weitere Wertebereichseinschränkungen zu einem global definierten Datentyp vorgeben.
159
3
3. Komplexe Typen und Inhaltsmodelle
32_03.xsd: Ableitung durch Einschränkung
3
ÄÄ Ableitung durch Erweiterung Ausgehend von einem global definierten Datentyp lässt sich bei der Deklaration eines Elements dieser Datentyp als Basistyp nehmen und erweitern. Wenn es sich um einen als simpleType definierten globalen Datentyp handelt, besteht die Erweiterung nur aus der zusätzlichen Angabe eines Attributs.
32_04.xsd: Globaler einfacher Typ und lokale Erweiterung mit Attribut
Dieses Vorgehen entspricht inhaltlich, nämlich zu einem Element mit einem Textknoten und einem Attribut zu kommen, exakt der folgenden Technik. Hier definiert man das Attribut im global vorhandenen Datentyp, benötigt allerdings keinen simpleType-, sondern einen complexType-Container für die zusätzliche Angabe des Attributs. Innerhalb des
160
3. Komplexe Typen und Inhaltsmodelle
complexType-Containers befindet sich dann wiederum – wie schon oben im lokalen Fall beschrieben – ein simpleContent-Container, da ein Textknoten angelegt werden soll.
3
Der Aufruf kann dann entweder ganz einfach über
oder auch über
32_05.xsd: Globaler komplexer Typ mit Attribut
erfolgen, wobei natürlich der zweite Aufruf nur darauf ausgerichtet oder nur dann sinnvoll ist, sobald weitere Eigenschaften hinzutreten. In der zuvor gezeigten Form sind sie jedoch völlig gleichwertig. Wie gerade erwähnt, besteht bei einem simpleType nur die Möglichkeit, bei der Ableitung durch Erweiterung ein Attribut einzufügen. Dies sähe dann folgendermaßen aus:
161
3. Komplexe Typen und Inhaltsmodelle
32_06.xsd: Ableitung durch Erweiterung bei einem einfachen globalen Typ
ÄÄ Ableitung durch Einschränkung Bei der Ableitung durch Einschränkung greift man dagegen auf einen global vorhandenen Datentypen (einfach oder komplex definiert) zurück und gibt für seinen Basistyp wiederum gültige Fassetten im restriction-Container der Element-Deklaration vor.
32_07.xsd: Ableitung durch Einschränkung
162
3. Komplexe Typen und Inhaltsmodelle
3. 2. 2. Komplexe Inhalte Bei der Modellierung eines Eltern-Elements modelliert man immer einen komplexen Inhalt. Dies war schon beim allerersten Beispiel zu sehen, da das Wurzelelement normalerweise immer ein Eltern-Element ist. Ansonsten bestünde das Instanzdokument lediglich aus einem Textknoten (oder sogar aus einem leeren Element) und aus möglichen Attributen. In diesem Abschnitt soll die für die Modellierung von Eltern-Elementen notwendige Syntax noch einmal im Detail vorgestellt werden, wobei auch die Fesseln, die sich durch die standardmäßige Verwendung von sequence bei der Modellierung und beim Aufbau der Dokumente ergab, gelöst werden sollen.
3. 2. 2. 1 Reihenfolge Als Beispiel für die beiden Techniken Reihenfolge und Auswahl soll folgendes Instanzdokument verwendet werden. Es enthält eine Kundenliste, die um Informationen zur Adresse oder zu detaillierten Umsätzen erweitert werden könnte. Doch bereits in ihrer Schlichtheit ist sie für eine Diskussion, mit welchen Methoden ein solches Dokument modelliert werden könnte, sehr interessant. Für jede Element Kunde gibt es ein Attribut Typ, das darüber Auskunft gibt, ob es sich um einen Geschäftskunden oder einen Privatkunden handelt. Geschäftskunden enthalten innerhalb des Name-Elements die beiden Kind-Elemente Firma und Branche mit den entsprechenden Textknoten, während Privatkunden im gleichen Element die beiden Kind-Elemente Vorname und Nachname speichern. Das Problem besteht nun darin, dieses Inhaltsmodell zu definieren, das in Abhängigkeit vom Kundentyp unterschiedliche Kind-Elemente aufweist. Fleckner + Söhne GmbH + Co. KG Fördergurte Gummi Kunststoffe 703.43 Erdle
163
3
3. Komplexe Typen und Inhaltsmodelle
Johann 229,45
32_08.xml: Kundenliste mit Geschäfts- und Privatkunden
3
Mit der Schema-Komponente sequence legt man für die innerhalb des von ihr aufgespannten Containers deklarierten Elemente eine Reihenfolgenbeziehung fest. Die einzelnen Elemente müssen genau in der Reihenfolge, in der sie innerhalb von sequence erscheinen, auch im Instanzdokument auftreten. Dabei sind gleichzeitig die Häufigkeitsbeschränkungen in minOccurs und maxOccurs für jedes Element zu berücksichtigen, wobei solche Häufigkeitsbeschränkungen als Gruppe auch für das gesamte sequence-Element gelten. Die allgemeine Syntax lautet wie folgt: Inhalt: (annotation?, (element | group | choice | sequence | any)*)
Eine erste Alternative für die Modellierung dieser Struktur besteht darin, jedes Element in seiner im aktuellen Instanzdokument auftretenden Reihenfolge in einer sequence zu deklarieren. Sie legt die Reihenfolge der in ihr deklarierten Elemente genauso fest, wie ihre Deklarationsreihenfolge im XSD-Dokument ist. Da man im einen Fall die beiden Elemente Firma und Branche besitzt und im anderen Fall Nachname und Vorname, setzt man überall minOccurs und maxOccurs auf 0. Dies hat den Nachteil, dass nicht mehr klar ist, welche beiden Elemente zusammen gehören, sodass eigentlich eine Gruppe deklariert werden müsste. Doch dies ist Thema eines späteren Abschnitts. Wichtig ist hier nur, dass für das obige Problem erstens eine Lösung gefunden wurde und dass diese Lösung zweitens sich der Häufigkeitsbeschränkung über die Angabe einer Element-Reihenfolge mit Hilfe von sequence bedient.
164
3. Komplexe Typen und Inhaltsmodelle
32.08.xsd: Modellierung einer Reihenfolge
Als Grafik ergibt dies ein Bild, das sowohl die Reihenfolge wie auch die optionalen Häufigkeiten und fehlende Gruppierung zeigt.
Abbildung 3.16: Angabe einer Reihenfolge
Eine weitere Reihenfolge in diesem Dokument richtet man für die wiederholt auftretenden Elemente Kunde und innerhalb dieses Elements für die Elemente Name und Umsatz ein. Innerhalb einer Reihenfolge drückt man die Häufigkeit von Elementen ausschließlich über die Häufigkeitsbeschränkungen der einzelnen Kind-Elemente aus, so z. B. in .
165
3. Komplexe Typen und Inhaltsmodelle
...
3
32_08.xsd: Definition von Reihenfolgen für wiederholt auftretende Elemente und Kind-Elemente
3. 2. 2. 2 Auswahl Die Schema-Komponente choice definiert eine Auswahl von Elementen, die alternativ als Inhaltsmodell für ein Eltern-Element auftreten können. Gruppen von Elementen lassen sich mit jeweils passenden Schema-Komponenten wie group aufrufen oder mit sequence deklarieren. Dabei sind gleichzeitig die Häufigkeitsbeschränkungen in minOccurs und maxOccurs für jedes Element zu berücksichtigen, wobei solche Häufigkeitsbeschränkungen als Gruppe auch für das gesamte choice-Element gelten. Die allgemeine Syntax lautet wie folgt: Inhalt: (annotation?, (element |
group | choice | sequence | any)*)
Im letzten Beispiel konnte nicht klar ausgedrückt werden, dass die Elemente Firma und Branche sowie Nachname und Vorname jeweils eine Gruppe bilden. Mittels einer Reihenfolge kann dies jetzt geschehen. Damit die beiden Reihenfolgen gleichzeitig als KindElementgruppen deklariert und als Alternativen verwendet werden können, setzt man sie komplett in einen Container aus choice-Elementen. Auf diese Weise kann nur eine der beiden Reihenfolgen tatsächlich im Instanzdokument realisiert werden, was einer guten Modellierung des vorliegenden Instanzdokumentes gleichkäme.
32_09.xsd: Modellierung über eine Auswahl
167
3
3. Komplexe Typen und Inhaltsmodelle
3 Abbildung 3.17: Modellierung über eine Auswahl
3. 2. 2. 3 Zusammenstellung Die Schema-Komponente all definiert eine Zusammenstellung von Elementen mit den Häufigkeitsbeschränkungen 0 oder 1 (d. h., entweder optionale oder einmal verpflichtende Elemente) und kann selbst auch nur genau einmal auftreten. Über die Deklaration der einzelnen Kind-Elemente innerhalb von all lässt sich keine Reihenfolge angeben. Die führt zur folgenden allgemeinen Syntax: Inhalt: (annotation?, element*)
So hätte man die erste Modellierungsvariante für dieses Dokument genausogut mit der all-Schema-Komponente realisieren können. Hierbei bleiben die vorgegebenen minOccurs-Werte erhalten. Im Gegensatz zur Verwendung von sequence ergibt sich hier nun eine größere Flexibilität bei der Reihenfolge, wenn sie denn auch gewünscht ist. Neben nicht gewollten Kombinationen von Nachname mit Branche sind andererseits auch die Reihenfolgen Vorname und Nachname oder Branche und Firma denkbar.
168
3. Komplexe Typen und Inhaltsmodelle
3
32_10.xsd: Optionale Elemente und Reihenfolgen
3. 2. 3. Gruppenbildung Elemente und Attribute treten häufig in Gruppen auf, wie es im letzten Beispiel schon für den Namen galt, der insgesamt aus den beiden Elementen Vorname und Nachname besteht. Derartige Gruppen lassen sich mit sequence innerhalb eines globalen komplexen Typs ablegen und dann an anderer Stelle benutzen. Über die Ableitung durch Erweiterung von einem globalen komplexen Typ hat man auch die Möglichkeit, weitere Elemente wie z. B. den Umsatz an diese Elemente anzuhängen, wobei allerdings einzig und allein ein Anhängen möglich ist. Mit Hilfe der Gruppenbildung über group und attributeGroup kann man hingegen eine globale Gruppe aus Elementen oder Attributen bilden, die nicht durch Ableitung, sondern durch Referenz lokal zum Einsatz kommt. Dies erleichtert die beliebige Positionierung von zusammenhängenden Strukturen innerhalb von Reihenfolgen oder Auswahlen, ohne dass man auf die Einschränkungen der Ableitungstechniken Rücksicht nehmen müsste. Folgendes XML-Instanzdokument enthält Daten für Privat- und Geschäftskunden mit Namen- und Adressbestandteilen, die schon aus anderen Zusammenhängen bekannt sind. Während einige Elemente innerhalb des Elements Kunde unterschiedlich sind, enthalten die Elemente Adresse und Telefon die gleichen Kind-Elemente. Es wäre also möglich, diese Gruppen aus Elementen auszulagern und für die Verwendung im Eltern-Element Kunde verfügbar zu machen. Sie könnten ebenso gut für eine Rechnung verwendet werden und in den Elementen Von und Nach erscheinen. Zusätzlich enthält das Element Kunde auch überall dieselben Attribute, und es ist aus anderen Beispielen bekannt, dass eine Auflistung der getätigten Anrufe ebenfalls diese Attribute verwenden könnte. Das Attribut Nr
169
3. Komplexe Typen und Inhaltsmodelle
stellt stets den Primärschlüssel dar, während Typ für die Unterscheidung zwischen privat und geschäftlich steht. Eine Auslagerung in eine globale Gruppe würde es gestatten, sich mehrfach auf dieselben Attribute zu beziehen.
3
Frommstedt Baustoffhandel GmbH + Co. KG Baustoffe 382.2
Bolkerstr. 31 40213 Düsseldorf
211 450204 Puschhof Michael 138.84 Wupperstr. 6 45219 Essen, Ruhr 2054 312569
32_11.xml: Privat- und Geschäftskunden mit Umsatzangabe
170
3. Komplexe Typen und Inhaltsmodelle
3. 2. 3. 1 Elementgruppen Um Elemente zu einer Gruppe2 zusammenzufassen, ohne einen globalen komplexen Typ zu definieren, stellt die XML Schema-Syntax die group-Schema-Komponente bereit. Sie enthält einen qualifizierten Namen, über den diese Gruppe lokal referenziert werden kann, um dort die in ihr deklarierten Elemente zu übergeben. Als Container-Element enthält sie ein vollständiges oder teilweises Inhaltsmodell, d. h., sie kann ebenfalls Reihenfolgen, Zusammenstellungen oder Auswahlen angeben. Die allgemeine Syntax hat die folgende Form: Inhalt: (annotation?, (all | choice | sequence))
Die globalen Gruppen platziert man wie andere globale Strukturen auch direkt unterhalb des schema-Elements ober- oder unterhalb des Wurzelelements. In diesem Fall erzeugt man eine Gruppe mit Namen Telefon, in der die Elemente Vorwahl und Telnr in einer Reihenfolge enthalten sind, und eine Gruppe mit Namen Adresse mit den in einem Reihenfolgencontainer untergebrachten Elementen Strasse, PLZ und Stadt. Sie enthalten also tatsächlich das gesamte Inhaltsmodell, das über eine einfache Referenzierung, die wiederum über das group-Element und das schon bekannten ref-Attribut gesteuert wird. Da man einen komplexen Inhalt in die Elemente Adresse und Telefon übernimmt, muss man noch diese lokale Verwendung von group noch in einen complexType-Container unterbringen.
2
Vgl.: http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions
171
3
3. Komplexe Typen und Inhaltsmodelle
3
...
32_11.xsd: Verwendung von Elementgruppen
In Abbildung 3.18 erkennt man, wie die beiden Gruppen im Element Kunde aufgerufen werden und dort ihr Inhaltsmodell entfalten.
172
3. Komplexe Typen und Inhaltsmodelle
3
Abbildung 3.18: Einsatz von Gruppen
Syntaktisch war der Einsatz nicht notwendig, da kein Quelltext verkürzt wurde. Allerdings bestünde die Möglichkeit, auf oberer Ebene die Kunden in einem PKunde- und GKundeElement zu erfassen und so auf das Typ -Attribut zu verzichten. Dadurch gewinnt man den Vorteil, weiterhin die gleiche Gruppe aus mehreren Elementen heraus referenzieren zu können. Bei der Verarbeitung einer mit diesem Schema-Dokument validierten XML-Datei könnte man dann auf die verschiedenen Kundengruppen mit //GKunde bzw. //PKunde und nicht mit //Kunde[@Typ=“g“] bzw. //Kunde[@Typ=“p“] zugreifen. Neben der Verkürzung des Quelltexts durch den Einsatz von Gruppen kann man eine Verlängerung desselben registrieren, der durch den wiederholten Aufruf der Referenzen verursacht wird. Hier gilt es abzuwägen, inwieweit das Schema-Dokument beispielsweise zukünftige Änderungen ausgerichtet sein soll. Eine Auslagerung erleichtert nämlich die Pflege erheblich. Neben den allgemeinen Fragen rund um die Modellierungsvarianten, die sich über die flexible XML Schema-Syntax ergeben, gibt der folgende Quelltextauszug darüber Auskunft, wie Gruppenreferenzen im Gegensatz zu Ableitungen an beliebigen Stellen innerhalb von Reihenfolgen zu platzieren sind. Man nennt innerhalb der verschiedenen Kunden-Elemente die einzelnen Kind-Elemente wie Nachname oder Vorname und fügt dann die Gruppenreferenz genau dort ein, wo das entsprechende Eltern-Element benötigt wird. Dies hätte dann die folgende Form:
173
3. Komplexe Typen und Inhaltsmodelle
3
...
174
3. Komplexe Typen und Inhaltsmodelle
…
3
32_12.xsd: Mehrfache Verwendung von Gruppen
Abbildung 3.19: Verwendung von Gruppen bei mehreren Elementen
Abbildung 3.19 zeigt noch einmal schematisch, wie an unterschiedlichen Stellen innerhalb der Deklarationen die Gruppen referenziert werden. Durch eine Auslagerung gewinnt man bei einer solchermaßen diskutierten Dokumentstruktur tatsächlich die Möglichkeit, die
175
3. Komplexe Typen und Inhaltsmodelle
gleichen Inhaltsmodelle bzw. Eigenschaften von einer zentralen Stelle im Dokument aus an unterschiedliche Orte zu übertragen.
3
In den zurückliegenden Modellierungsversuchen platzierte man den Gruppenaufruf innerhalb eines anderen Elements, das dadurch zum Eltern-Element der innerhalb der Gruppe deklarierten Elemente wurde. Dies erforderte einen complexType-Container um den Gruppenaufruf. Natürlich kann man auch unmittelbar in einer Gruppe Eltern-Elemente deklarieren. Dies bedeutet für das vorliegende Beispiel, innerhalb der Gruppe einen Container (Reihenfolge, Auswahl oder Zusammenstellung) als oberstes Element zu platzieren und dann die ansonsten auch lokal notwendigen Deklarationen festzulegen. Für die spätere Referenz verkürzt dies den Quelltext auf einen einfachen Gruppenaufruf mit Hilfe des refAttributs im group-Element ohne einen speziellen Container.
...
176
3. Komplexe Typen und Inhaltsmodelle
...
32_13.xsd : Eltern-Elemente in Gruppen
Abbildung 3.20 illustriert diesen Zusammenhang recht eindrücklich: Die Elemente Adresse und Telefon befinden sich nun nicht mehr vor bzw. außerhalb des Gruppenaufrufs und der dann aufgerufenen Elemente, sondern innerhalb bzw. nach diesem Aufruf und damit innerhalb der global deklarierten Gruppe.
Abbildung 3.20: Eltern-Elemente in Gruppen
177
3
3. Komplexe Typen und Inhaltsmodelle
3. 2. 3. 2 Attributgruppen Für Attribute, die entweder an mehreren Stellen im Schema-Dokument auftreten oder die generell zentral gepflegt werden sollen, gelten die gleichen Überlegungen, um die Vorteile der Auslagerung zu nutzen.
3
Die allgemeine Syntax hat die folgende Form: Inhalt: (annotation?,
((attribute | attributeGroup)*, anyAttribute?))
Innerhalb des attributeGroup-Containers3 deklariert man die benötigten Attribute wie bei einer lokalen Deklaration und vergibt für die gesamte Gruppe einen eindeutigen Namen. Über dasselbe Element und den vergebenen Namen lässt sich dann an der Stelle der Element-Deklaration, an der Attribute deklariert werden können, diese Gruppe aufrufen, sodass ihre Inhalte für dieses Element nutzbar gemacht werden können. ...
3 Vgl.: http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions
178
3. Komplexe Typen und Inhaltsmodelle
3
32_12.xsd: Verwendung von einer Attributgruppe
3. 3. Spezielle Inhaltsmodelle Nach der Deklaration von Textknoten und Elementen bzw. zusätzlichen Attributen als einfacher oder komplexer Inhalt besteht natürlich auch die Möglichkeit, leere und gemischte Inhalte anzugeben.
3. 3. 1. Gemischte Inhaltsmodelle Einer von diesen Spezialfällen ist das gemischte Inhaltsmodell, das im nachfolgenden Instanzdokument beispielhaft angeführt wird. Dabei enthält ein Element sowohl einen Textknoten als auch weitere Kind-Elemente. Dies findet man sehr häufig bei dokumentenorientierten Modellierungen, die solche Elemente wie betont, Abkuerzung oder Akronym besitzen. Dabei werden innerhalb eines Fließtextes noch einmal gesondert einzelne Bestandteile herausgegriffen und ausgezeichnet. Im Beispiel handelt es sich um eine Zusatzinformation, die neben der Anzahl der Neukunden in einem Monat auch die Anzahl der sich summierenden Gesamtkunden angibt. 10 10 21
31
33_01.xsd: Gemischtes Inhaltsmodell
179
3. Komplexe Typen und Inhaltsmodelle
3. 3. 1. 1 Deklaration
3
Für die Modellierung eines solchen gemischten Inhaltsmodells verwendet man ganz einfach für die complexType-Schema-Komponente in globaler oder lokaler Verwendung das Attribut mixed mit dem Wert true. Es ist dabei nicht möglich, einen Datentyp für den Text in dem modellierten Element Neukunden anzugeben. Es kann sich demnach sowohl um Zahlen, einfache Zeichenketten als auch um andere Strukturen handeln, die nachher bei der Verarbeitung extra ausgefiltert werden müssten. Dies ist ein grundsätzlicher Nachteil, der allerdings die Flexibilität bietet, den Text überall zu positionieren. Man kann nämlich die Reihenfolge nicht angeben, in der Text und Elemente auftreten sollen. Während es bei dem vorliegenden Beispieldokument sicherlich interessant und nützlich wäre, erst die Zahl der neuen Kunden zu speichern und dann die Gesamtanzahl der Kunden zu erfassen, könnte es genauso gut in umgekehrter Reihenfolge geschehen. Dies mag bei dokumentorientierter Modellierung erwünscht sein, bei der datenorientierten ist es alles andere. Ein Element wie betont kann ja gerade überall in einem Text auftreten und nicht nur nach einer bestimmten Menge von Text oder ganz am Ende. Möchte man hier also weniger Spielraum zulassen, sollte man lieber zwei Kind-Elemente mit der Anzahl der Neuzugänge und der zugehörigen Anzahl der Gesamtkunden des aktuellen Monats deklarieren.
33_01.xsd: Gemischter Inhalt
180
3. Komplexe Typen und Inhaltsmodelle
In Abbildung 3.21 erkennt man schematisch, dass Neukunden Text enthält und gleichzeitig optional eine Auswahl, die das Element Gesamt speichert. Über eine Reihenfolge von Text und Element sowie den Datentyp des Textes wird hier nichts ausgesagt.
3 Abbildung 3.21: Leeres Inhaltsmodell
3. 3. 1. 2 Ableitung Inhaltsmodelle mit gemischtem Inhalt lassen sich natürlich auch ableiten, wobei wiederum die beiden grundsätzlichen Unterscheidungen zwischen Ableitung durch Erweiterung und Ableitung durch Einschränkung zu treffen sind. Dies soll nur relativ kurz angeführt werden, da sich die Ableitungsregeln prinzipiell genauso wie die zugehörigen Ableitungsregeln für komplexe Inhaltsmodelle verhalten. ●●
Ableitung durch Erweiterung: Der globale komplexe Typ dient als Basis für eine Erweiterung um Elemente und Attribute in Form einer Reihenfolge, die zunächst aus den Elementen und Attributen besteht, die schon im Inhaltsmodell des globalen komplexen Typs vorhanden sind. Diese Reihenfolge wird dann ergänzt um die neuen Elemente und Attribute. Wichtig ist hier, dass die Reihenfolge der Elemente im globalen komplexen Typ nicht verändert werden kann. Stattdessen handelt es sich um ein Anhängen von neuen Strukturen.
●●
Ableitung durch Einschränkung: Der globale komplexe Typ dient als Basis für eine Einschränkung um Elemente und Attribute, wobei keine syntaktische oder inhaltliche Gemeinsamkeit mit den anderen Ableitungstechniken besteht. Zwar verringert sich durch die Einschränkung die Anzahl und Auswahl der Elemente und Attribute, doch muss dabei das komplette neue Inhaltsmodell definiert werden. Es besteht über den Aufruf des globalen komplexen Typen im type-Attribut des Elements hinaus lediglich ein Hinweis, dass eine übergeordnete ähnliche Struktur vorhanden ist.
Eine beispielhafte Erweiterung des vorliegenden XML-Dokuments führt für jeden Datensatz noch ein Element Stadt ein, in dem die Stadt gespeichert wird, der die neu gewonnenen Kunden entstammen. Alternativ ist auch noch ein Element Kommentar zugelassen,
181
3. Komplexe Typen und Inhaltsmodelle
das besonders viele Neuzugänge mit einer vielleicht in diesem Monat durchgeführten Werbeaktion verknüpft. 10
10
21 Essen, Ruhr
31
Essen, Ruhr
33_02.xml: Zusätzliche, optionale Elemente
Zunächst benötigt man für die Ableitung einen global vorhanden komplexen Typ namens NKTyp, der die Grundbausteine der Neukundenstatistik enthält. Diese besteht nur aus einem einzigen Kind-Element Gesamt, das bereits in der ersten Version des XML-Dokuments vorhanden war. Dieser komplexe Typ dient nun als Basistyp für den Aufruf im base-Attribut des extension-Container-Elements, der die beiden neuen Elemente Stadt und Kommentar in einer Reihenfolge sowie die beiden Attribute Monat und Typ außerhalb der Reihenfolge umschließt.
182
3. Komplexe Typen und Inhaltsmodelle
3
33_02.xsd: Ableitung durch Erweiterung um Elemente und Attribute
In Abbildung 3.22 erkennt man deutlich, wie der für das Element Neukunden zugewiesene Typ NKTyp um die beiden optionalen Elemente Stadt und Kommentar erweitert wird.
Abbildung 3.22: Ableitung durch Erweiterung
183
3. Komplexe Typen und Inhaltsmodelle
ÄÄ Ableitung durch Einschränkung
3
Bei der Ableitung durch Einschränkung greift man auf einen globalen komplexen Typ zu, der mit einem gemischten Inhaltsmodell deklariert wurde, um dann seine Eigenschaften zu beschränken. Dies geschieht durch ein Verbot von Attributen und Elementen über maxOccurs oder der Verringerung der Attributverwendung auf optional oder prohibited bzw. den Beschränkung des Wertebereichs durch die Wertfestsetzung in Attributen durch fixed oder die Anwendung von Fassetten für Elemente oder Attribute. Das nachfolgende Beispiel erlaubt das global eingeführte Element Vorjahr mit dem Vorjahreswert für die Gesamtkundenzahl lokal nicht mehr und setzt den Kundentyp pauschal auf Geschäftskunde. Dabei ist – wie bei der Ableitung von globalen komplexen Typen üblich – die Angabe des kompletten Inhaltsmodells nötig, sodass die Angabe des Basistyps im type-Attribut des restriction-Elements lediglich dazu dient, eine syntaktisch nicht auswertbare Beziehung zum globalen komplexen Typ anzugeben.
184
3. Komplexe Typen und Inhaltsmodelle
3
33_03.xsd: Ableitung durch Einschränkung
Aus Abbildung 3.23 geht vor allen Dingen deutlich hervor, dass bei der Ableitung von globalen komplexen Typen mit gemischtem Inhaltsmodell in Wirklichkeit ein eigenes, lokales Inhaltsmodell mit genau den Eigenschaften angegeben wird, die lokal benötigt werden. Eine Beziehung zu einem global vorhandenen komplexen Typen wird zwar im base-Attribut angegeben, ist aber quasi nur aus Dokumentationszwecken wichtig.
Abbildung 3.23: Ableitung durch Einschränkung
3. 3. 2. Leere Inhaltsmodelle Ein weiterer Spezialfall ist der leere Inhalt eines Elements. Dies kann entweder durch fehlende Werte in einer Anwendung oder einer Datenbank (vorliegender Fall) oder durch konsequente Verwendung von Attributen geschehen, bei denen es gar nicht mehr auf durch ein Element gespeicherte Werte ankommt. Den häufigen Einsatz von Attributen könnte
185
3. Komplexe Typen und Inhaltsmodelle
man dazu nutzen wollen, über die Attributachsen mit Hilfe von @attributname auf die einzelnen Attribute eines Wertes zuzugreifen und damit eine besondere Schreibweise im Verarbeitungsquelltext zu erreichen.
3
3. 3. 2. 1 Deklaration Die XML Schema-Syntax bietet kein zusätzliches Attribut wie bei gemischtem Inhalt, mit dem man durch den Wert true leeren Inhalt einrichten kann. Stattdessen verwendet man die gewöhnlichen Datentypen in Kombination mit lokalen oder globalen einfachen wie komplexen Typen. Für folgendes Beispiel lassen sich zwei Elemente einrichten, die leeren Inhalt akzeptieren. Während das Element Datum nur aus leerem Inhalt bestehen soll, kann es für das Element Tarif durchaus leeren Inhalt geben, wenn der Zahlenwert eigentlich 0 wäre. 42391,75 72538,02 40082,64
33_04.xml: Leere Elemente
Da das Element Datum nur aus leerem Inhalt bestehen soll und demnach die Inhalte lediglich in seinen Attributen gespeichert werden, verzichtet man auf die Angabe eines Datentyps und macht keine Angabe darüber, welchen Datentyp ein möglicher Textknoten haben soll. Auf diese Weise verhindert man, dass überhaupt ein Textknoten in diesem Element untergebracht wird. Die Attribute speichert man im untergeordneten complexType-Container. Für das Element Tarif hingegen ist sowohl der leere Inhalt als auch ein Textknoten möglich. Einerseits verwendet man hier den Datentyp string, um Zahlen zu speichern, auf die man nachher nicht ohne Umwandlung in eine Zahl zugreifen kann, auf der anderen Seite ist dies die einzige Möglichkeit, auch eine leere Zeichenkette abzuspeichern. Würde
186
3. Komplexe Typen und Inhaltsmodelle
man hier den Datentyp decimal aufrufen, könnte man gerade kein leeres Element Tarif speichern. Die Deklaration der Attribute erfolgt dann wie gewohnt innerhalb eines complexType-Containers.
3
33_04.xsd: Modellierung von leerem Inhalt
187
3. Komplexe Typen und Inhaltsmodelle
3. 3. 2. 2 Ableitung
3
Auch für leere Inhaltsmodelle lassen sich die beiden bekannten Ableitungen durch Erweiterung und durch Einschränkung durchführen. Allerdings gibt es hier noch weniger Möglichkeiten als sonst, da ja weder Fassetten für den Inhalt als Einschränkung noch Kind-Elemente als Erweiterung denkbar sind. Wo kein Inhalt zugelassen ist, kann man ihn natürlich nicht noch weiter einschränken; und auch die Erweiterung beschränkt sich auf zusätzliche Attribute, aber keinesfalls auf weitere Kind-Elemente, die vom globalen Typ gar nicht vorgesehen sind. Daher sind die beiden folgenden Beispiele hauptsächlich als Anschauungsmaterial mit Hilfe von Attributdeklaration und -beschränkungen für die beiden Fälle des zugelassenen und des geforderten leeren Inhalts zu verstehen: Beim zugelassenen leeren Inhalt kann das Element wie z. B. bei Tarif auch keinen Textknoten beinhalten. Bei gefordertem leeren Inhalt darf dagegen kein Textknoten als Blatt erscheinen.
ÄÄ Ableitung durch Erweiterung Für beide Elemente, für die leerer Inhalt modelliert werden soll, erstellt man globale komplexe Typen. Komplex deswegen, weil Attribute für beide Typen deklariert werden. Für den globalen komplexen Typ TarifTyp sind auch leere Textknoten zulässig, weswegen hier string als Basistyp zum Einsatz kommt, während für den globalen komplexen Typ DatumTyp gar kein Textknoten zulässig ist, weswegen auf die Angabe eines Datentyps und eines entsprechenden Containers verzichtet werden kann. Beim Aufruf und der folgenden Erweiterung kann man für beide Elemente nur auf die Attributdeklarationen der globalen komplexen Typen zugreifen und diese um weitere Attribute vergrößern. Auch hier kann man auf weitere Container verzichten.
188
3. Komplexe Typen und Inhaltsmodelle
3
33_05.xsd: Ableitung durch Erweiterung
189
3. Komplexe Typen und Inhaltsmodelle
ÄÄ Ableitung durch Einschränkung
3
Bei der Ableitung durch Einschränkung ruft man die global und im Vergleich zum vorherigen Beispiel mit allen Attributen ausgestatteten komplexen Typen auf und verringert ihre Verwendung z. B. von required nach optional oder verkleinert ihren Wertebereich. Lediglich beim zugelassenen leeren Inhalt, wie er durch den globalen komplexen Typ TarifTyp ausgedrückt wird, könnte man auch durch geeignete Fassetten den Wertebereich für den zugelassenen Textknoten beschränken. Hier sind natürlich nur solche Fassetten einsetzbar, die für den verwendeten Datentyp string geeignet sind, der ja verwendet wurde, um auch leeren Inhalt zuzulassen.
190
3. Komplexe Typen und Inhaltsmodelle
3
33_06.xsd: Ableitung durch Einschränkung
191
Schlüssel und Verweise
4. Schlüssel und Verweise
4. Schlüssel und Verweise Da die Beispiele in diesem Buch aus einer Datenbank stammen, ist es nur offensichtlich, dass die im Attribut Nr versteckten Werte Primärschlüssel- oder Fremdschlüsselwerte in den jeweiligen Datenbanktabellen repräsentieren. Durch die Kürze der Dokumente war es bisher nicht notwendig, auf solche Schlüssel ein Auge zu werfen, da ein entsprechendes Eltern-Element sämtliche durch den Wert in einem Nr-Attribut repräsentierten Daten als Kind-Elemente enthielt. Längere Dokumente hingegen, in denen – auf die Dokumentzeilen bezogen – tiefer liegende Strukturen auf solche Werte verweisen, benötigen einen Mechanismus, mit dem bereits im Schema-Dokument klar beschrieben ist, welche Werte Schlüssel darstellen, welche dazu Referenzen bieten und welche für solche Überlegungen unwesentlich sind. Für die Abbildung von Schlüsseln und Verweisen lassen sich die Datentypen aus der herkömmlichen DTD nutzen. Sie wurden zusätzlich in die XML Schema-Syntax übernommen, um bei der Transformation von DTD-Dokumenten in XML Schema-Dokumente leichte Übertragungsmöglichkeiten bereitzustellen. Allerdings bietet XML Schema auch eigene Techniken.
4. 1. ID und IDREF/IDREFS Für Anwendungen, deren Datenströme ohnehin schon mit einer DTD validiert wurden, eignet sich die Verwendung der bereits bekannten Schlüssel und Verweise, da notwendigerweise in den Datenströmen bereits auf die Einschränkungen, die dieses Format erforderte, eingegangen wurde. Zu diesen Einschränkungen gehören die folgenden: ●●
Der Wert eines Schlüssels muss in der lexikalischen Dimension einem unqualifizierten XML-Namen entsprechen. Dies bedeutet, dass keine Leerzeichen zulässig sind und die Werte nicht mit einer Zahl beginnen können. Damit sind sofort alle Schlüssel, die nur aus Zahlen bestehen, für dieses Format nicht geeignet, da sie ein irgendwie geartetes Präfix in Form mindestens eines Anfangsbuchstabens benötigen. Zudem können keine Schlüssel verwendet wer-
193
4
4. Schlüssel und Verweise
den, die Leerzeichen beinhalten und sich z. B. syntaktisch aus mehreren Einheiten wie ein ISBN-Wert zusammensetzen. ●●
4
Der Schlüsselwert muss innerhalb des Dokuments völlig einzigartig sein. Es darf also nicht noch einmal der gleiche Wert als Schlüssel auftauchen. Dies gilt für alle Elemente, und zwar auch dann, wenn für verschiedene gerade nicht gleiche Elemente (Kunde, Produkt etc.) die gleiche Nummer verwendet würde und sich dieser Wert nur zufällig als gleich herausstellt. Dies kann insbesondere bei reinen Zahlen geschehen, wobei hier schon durch einen vorgestellten Buchstaben für die erste Einschränkung ein Duplikat vermieden werden kann. Diese Buchstaben dienen also dazu, solche gleichwertigen, aber nicht gleichen Elemente voneinander zu unterscheiden.
In der DTD-Syntax war es nur möglich, die verschiedenen Schlüsseldatentypen für Attribute, nicht aber für Elemente zu verwenden, da Elemente ja gar keine Datentypen kannten. Diese Einschränkung entfällt in XML Schema. Es wird allerdings empfohlen, sie zu berücksichtigen, um vollständige Kompatibilität auf dem Gebiet der Schlüsselmodellierung bzw. bei der Übertragung von einer DTD in ein XML Schema-Dokument zu gewährleisten. Die herkömmliche DTD bot verschiedene Datentypen für die Modellierung von Schlüsseln und Verweisen an. Es sind dies die folgenden, die auch im Namensraum xs für ein XML Schema-Dokument nutzbar sind: ●●
ID: Schlüsselwert für ein Attribut (empfohlen) und ein Element
●●
IDREF: Verweis auf einen existierenden Schlüssel für ein Attribut (empfohlen) und ein
Element ●●
IDREFS: Liste von Schlüsseln als Tokenliste für ein Attribut (empfohlen) und für ein
Element
4. 1. 1. Schlüssel- und Verweisdefinition Die Rechnungen speichert die für die XML-Dokumente verwendete Datenbank in zwei Tabellen namens RECHNUNG und POSTEN, zwischen denen eine 1:n-Beziehung besteht. Jede Rechnung besitzt eine eindeutige Nummer, die sich wiederum auf einen speziellen Kunden, der über einen Fremdschlüssel referenziert wird, und einen Abrechnungszeitraum bezieht. Die einzelnen Posten beziehen sich auf die verschiedenen Tarife und auf eine einzelne
194
4. Schlüssel und Verweise
Rechnung und repräsentieren die einzelnen Werte, die zur Gesamtsumme der Rechnung führen. Für die Posten ist die Rechnungsnummer ein Fremdschlüssel. Folgendes XML-Dokument enthält zwei abgekürzte Rechnungen mit drei und zwei Posten, die sich jeweils auf den Abrechnungszeitraum April 2003, die Kunden 5 und 9 und zwei bzw. drei Tarife in der Postenliste beziehen. Die Elemente Rechnung und Kunde speichern ihren Primärschlüsselwert einmal als Attribut Nr und einmal als Textknoten, wobei ausgehend von jedem Posten-Element in einem RefNr-Attribut auf eine Rechnung verwiesen wird. Jeder Posten enthält zusätzlich seinen Primärschlüsselwert in einem Nr-Attribut. Für alle Primär- und Fremdschlüsselwerte wurde ein Präfix, bestehend aus dem ersten Buchstaben des zugehörigen Elements erstellt, d. h., die Rechnungsnummern beginnen mit einem R und die Postennummern mit einem P. Für die Modellierung mit einer DTD ist dies für das Element Kunde nicht notwendig, da es gar nicht möglich ist, es als Schlüsselwert zu deklarieren, weil der ID -Datentyp ausschließlich für Attribute verwendbar ist. Bei einer Modellierung mit XML Schema hingegen besteht die Möglichkeit, auch ein Element mit diesem Datentyp auszustatten, sodass hier ebenfalls ein Präfix benötigt wird. 6.38 K5 Frühstück 0.85 Mittagspause 1.51 Mondschein2 1.44 3.89 K9
195
4
4. Schlüssel und Verweise
Frühstück 0.44
Mittagspause 2.8
4
41_01.xml: Rechnungsliste mit Schlüsseln und einfachen Verweisen
Abbildung 4.1: Elemente der Rechnungsliste
Kurz soll noch einmal geschildert werden, wie die jeweiligen Nr-Attribute bisher den Datentyp erhielten und die einfachen Schlüsselbezüge mit IDREF modelliert wurden. Für das Element Kunde ist nur PCDATA als Inhaltsmodell möglich, weil die DTD keine Datentypen unterstützt, weshalb hier keine Schlüsselmodellierung durchführbar ist. Für den Schlüsselverweis im RefNr-Attribut des Posten-Elements verwendet man dagegen den Datentyp IDREF, der genau auf einen Wert im gesamten Dokument verweist.
Datum CDATA #REQUIRED
Typ CDATA #REQUIRED
Nr ID #REQUIRED RefNr IDREF #REQUIRED
41_01.dtd: Schlüssel und Verweise
In XML Schema verwendet man exakt die gleichen Datentypen, die man allerdings sowohl Attributen als auch Elementen zuweisen kann. Daher war es nötig, auch im Element Kunde den Textknoten als unqualifizierten XML-Namen mit vorgesetztem Präfix in Form des Buchstabens K einzugeben. Hier sieht man aufgrund des zusätzlichen Attributs auch sehr schön, dass diese Datentypen zwar wegen ihrer Namensgebung und Herkunft eine Besonderheit darstellen, sich aber letztlich genauso wie alle anderen Datentypen verhalten und auch in einem extension-Container als Basistyp aufgerufen werden können. Für dieses Element wie für die beiden Nr-Attribute, die auch global hätten deklariert werden können, verwendet man den xs:ID -Datentyp. Für den einfachen Schlüsselverweis hingegen kommt der schon aus der DTD bekannte Datentyp xs:IDREF zum Einsatz.
197
4
4. Schlüssel und Verweise
4
41_01.xsd: Schlüssel und einfache Verweise
198
4. Schlüssel und Verweise
4
Abbildung 4.2: Schlüssel und Verweise
4. 1. 2. Mehrfachverweise Im vorangehenden Beispiel konnte man nur einen einzigen Schlüssel referenzieren, d. h., man befand sich auf der rechten Seite einer 1:n-Beziehung. Um sich nun auf die linke Seite zu begeben und mehrere Schlüssel gleichzeitig aus einem Attribut oder Element heraus zu referenzieren, kann man den speziellen Datentyp xs:IDREFS verwenden. Er gestattet die Speicherung einer Tokenliste und erwartet demnach eine Reihe von unqualifizierten Namen, wie sie vom xs:ID -Datentyp gespeichert werden, die dann gleichzeitig angesprochen werden können. Ein solcher Verweis befindet sich im nächsten Instanzdokument, wobei von einer Rechnung aus die vom Kunden verwendeten Tarifnummern in einem Tarife-Attribut gespeichert werden. Sie befinden sich, wie oben bereits beschrieben, in einer Tokenliste, die sich aus Werte zusammensetzt, die der ID -Datentyp abbildet.
199
4. Schlüssel und Verweise
6.38 K5
Frühstück 0.85
4
Mittagspause
1.51
Abendessen 2.04 Mondschein1 0.54 41_02.xml: Schlüssel und Mehrfachverweise
In einer herkömmlichen DTD, die hier zur Hälfte wiedergegeben wird, verwendet man den IDREFS-Datentyp, der natürlich nur für Attribute und nicht etwa für Elemente benutzbar ist. Er besitzt die gleichen Eigenschaften wie alle Schlüsseldatentypen in DTD, erwartet als einziger Unterschied jedoch die schon erwähnte Tokenliste, die sich aus unqualifizierten, für ID -Werte gültigen Namen zusammensetzt.
... 41_02.dtd: Mehrfachverweise in der DTD
In der XML Schema-Syntax existiert ein ähnlicher Datentyp namens xs:IDREFS, der allerdings sowohl für Attribute als auch für Elemente verfügbar ist und nur aus Gründen der Kompatibilität mit DTD-Strukturen ausschließlich für Attribute zum Einsatz kommen sollte. Ihn ruft man für das Eltern-Element Rechnung im Attribut Tarife auf, dessen Werte inhaltlich mit denen im ID -Datentyp gespeicherten Werte des Nr-Attributs von Tarif in einer Liste übereinstimmen.
...
201
4
4. Schlüssel und Verweise
...
4
41_02.xsd: Schlüssel und Mehrfachverweis
Abbildung 4.3 soll noch einmal den Unterschied zwischen den zuvor gezeigten einfachen Verweisen und den hier diskutierten mehrfachen Verweisen veranschaulichen. Während zuvor ein Wert in einem Verweisattribut mit einem Wert im Dokument übereinstimmte, stimmt hier jeweils ein Wert in einer Tokenliste mit einem Wert im Dokument überein. Der Mehrfachverweis entsteht nicht dadurch, dass ein Verweiswert mehrere Zielpunkte hat, sondern dadurch, dass in einem einzigen Verweisattribut über eine Tokenliste mehrere Startpunkte von Verweisen liegen, wodurch aus diesem Attribut heraus mehrere Verweise zu unterschiedlichen Zielpunkten eingerichtet werden können.
202
4. Schlüssel und Verweise
4
Abbildung 4.3: Mehrfachverweise
4. 2. Key, Unique und Keyref Die Einschränkungen durch die Verwendung der auf der DTD basierenden Schlüsseldefinition sind so erheblich, dass man sie tatsächlich nur benutzen sollte, wenn man ein existierendes Regeldokument nach XML Schema bringen möchte und die Werte für Schlüssel und Referenzen ohnehin z. B. den Anforderungen eines qualifizierten XML-Namens genügen. Für alle anderen Anwendungen, in denen das Schema-Dokument sofort mit Hilfe der Syntax von XML Schema konstruiert werden soll, sollte man die in diesem Abschnitt präsentierten Vorgehensweisen vorziehen.
4. 2. 1. Schlüssel über Für die Definition von Schlüsseln bzw. Eindeutigkeit stehen zwei Konzepte bereit. Sie weisen zwei getrennte Prüfmechanismen auf. Für die Definition der Eindeutigkeit verwendet
203
4. Schlüssel und Verweise
man die Schema-Komponente , während für einen reinen Schlüssel die Schema-Komponente zum Zug kommt. 4. 2. 1. 1 Definition von Schlüsseln
4
Die erste Möglichkeit, gewisse Textknoten oder Attributinhalte als Schlüsselwerte auszuzeichnen, bietet die gerade erwähnte Schema-Komponente . Neben der vermutlich ohnehin erwarteten Eigenschaft, dass Werte in einem Instanzdokument, den Inhalt von einem als Schlüssel gekennzeichnetem Element oder Attribut bilden, innerhalb eines bestimmten Gültigkeitsrahmens einzigartig sein müssen, bietet die Definition eines Schlüssels mit noch eine weitere Prüfung. Neben den inhaltlichen Bedingungen (keine Duplikate) muss auch eine Existenzbedingung erfüllt sein: Das als Schlüsselfeld identifizierte Attribut oder Element muss auch tatsächlich existieren. Dies ist ein Zusatz gegenüber der Eindeutigkeit, bei der lediglich der Inhalt innerhalb seines Gültigkeitsrahmens nicht doppelt im gleichen Feld – zu verstehen als Element oder Attribut – auftreten darf. Wie schon angedeutet, gilt ein Schlüssel nur innerhalb eines bestimmten Bezugsrahmens, der über ein entsprechendes Eltern-Element aufgespannt wird. Als Beispiel für die Definition und Wirkungsweise eines Schlüssels soll folgendes Rechnungsdokument mit zwei verschiedenen Rechnungen dienen. Als Novität enthalten nicht nur die Nr-Attribute Schlüsselwerte aus Datenbanktabellen, sondern auch das Element Kunde als Textknoten. Alle diese Schlüssel sind noch einmal gefettet gehalten. Auf den ersten Blick erkennbar sind sowohl die Kundennummern wie auch Posten- und Rechnungsnummern im gesamten Dokument unterschiedlich. Allerdings wäre es auch denkbar, dass die Postennummern für jede Rechnung einfach nur aufsteigend nummeriert und daher ihre Schlüsselwerte innerhalb einer Rechnung zwar einzigartig wären, im Dokument hingegen mehrfach vorkommen könnten. Auf diesen Umstand wird später in einem Vergleich noch genauer eingegangen, und zwar im Zusammenhang damit, wo der Schlüssel angesiedelt wird und welchen Lokalisierungspfad er dadurch erhält. 6.38 5 Frühstück
204
4. Schlüssel und Verweise
0.85
Mittagspause
1.51
3.89 9
4
...
42_01.xml: Schlüssel mit einfachen Zahlen
Es bieten sich unterschiedliche Möglichkeiten, Schlüssel für das oben abgedruckte Dokument zu formulieren. Die beiden interessantesten Varianten seien hier näher beschrieben. Die allgemeine Syntax für die Definition eines Schlüssels lautet: Inhalt: (annotation?, (selector, field+))
Die Syntax besteht aus einem name-Attribut, in dem ein für den Schlüssel innerhalb des Dokuments eindeutiger Name vergeben wird, über den dieser Schlüssel in einem Verweis auch angesprochen werden kann. Für die eigentliche Definition des Schlüsselwertes kommen zwei spezielle Elemente zum Einsatz: und , wobei nur ein -Element, allerdings mehrere -Elemente zulässig sind. Im xs:selector>-Element befindet sich ein XPath-Ausdruck, der ausgehend vom Element, in dem der Schlüssel definiert wird, das Element angibt, in dem der Schlüsselwert zu finden ist. Mit Hilfe des -Elements legt man dann fest, ob sich dieser Wert in einem Attribut, im Textknoten dieses Elements oder in einem anderen Element befindet. Im letz-
205
4. Schlüssel und Verweise
ten Fall wird der Textknoten automatisch ausgewählt. Für Attribute ist nur die Angabe im -Element zulässig. Beide zusammen sind also erforderlich, um tatsächlich auch den Wert und die Position zu ermitteln, der für die komplette Angabe des Schlüssels notwendig ist.
4
Ein erstes Beispiel definiert die folgenden Schlüssel für das gesamte Dokument, weil das Element, das die einzelnen Schlüssel enthält, das Element Rechnungen ist. Innerhalb seiner Gültigkeit dürfen demnach für das Element Kunde sowie die beiden Nr-Attribute von Posten und Rechnung keine doppelten Werte bzw. nur eindeutige Werte erscheinen. Für die Definition der einzelnen schlüsseltragenden Elemente und Attribute ändert sich bei ihrer Deklaration nichts. Lediglich ihr Ort innerhalb des Matrjoschka-Designs (das ein Verständnis der Pfad-Angabe im selector-Attribut sehr vereinfacht) ist für die Definition der einzelnen Schlüssel indirekt von Bedeutung. Die drei Schlüssel befinden sich ganz unten und damit außerhalb der Angabe des Inhaltsmodells für das Element Rechnungen, könnten sich allerdings auch ganz oben befinden. Mit den XPath-Ausdrücken Rechnung/ Posten, Rechnung/Kunde und Rechnung in den selector-Attributen findet man ausgehend vom Rechnungen-Element jeweils die Elemente Posten, Kunde und Rechnung. Mit den XPath-Ausdrücken @Nr und . (entspricht text()) in den field-Attributen findet man die Textinhalte in den beiden Nr-Attributen und dem Textknoten. Abgesehen von der Syntax bedeutet diese Konstruktion, dass für das gesamte Dokument alle drei genannten Elemente und Wertinhalte eindeutig sein müssen, weil Rechnungen alle anderen Elemente enthält und die Schlüssel innerhalb seines Gültigkeitsbereichs definiert wurden. Es ist daher nicht zulässig, dass eine Rechnung den gleichen Wert in ihrem Nr-Attribut wie eine andere Rechnung hat, was ebenso für das Element Kunde und das Nr-Attribut des Elements Posten gilt. Dies gilt allerdings – im Gegensatz zu ähnlichen Definitionen mit Hilfe der DTD-Konstruktionen über ID -Attribute – nicht für den Wert an sich. Während in einem ID -Attribut der Wert 9 nicht nur nicht erlaubt wäre, da er nicht mit einem Buchstaben beginnt, sondern es wäre auch nicht gestattet, dass eine Rechnung und ein Kunde die gleiche Nummer besitzen, weil eine zusätzliche Einschränkung für die ID -Attribute ja gerade besagt, dass die qualifizierten Namen dokumentweit einzigartig sein müssen. Darüber hinaus verstieße es gegen die Regeln, einen Schlüsselwert in einem Element wie Kunde zu platzieren, da einem Elementinhalt kein ID -Datentyp zugewiesen werden könnte.
206
4. Schlüssel und Verweise
4
207
4. Schlüssel und Verweise
4
42_01.xsd: Definition von Schlüsseln
Abgesehen von der Syntax für die Definition von Schlüsseln mit Hilfe der Elemente und ist natürlich die korrekte Verwendung der Lokalisierungspfade in den XPath-Ausdrücken von Bedeutung. Sie wird innerhalb eines Matrjoschka-Designs besonders einfach, weil die Elemente ja bereits so verschachtelt angeordnet sind, dass man sehr leicht über die Verschachtelungsschritte z. B. über die -Schema-Komponenten die zugehörigen Pfade findet.
Abbildung 4.4: Baumstruktur im Matrjoschka-Design
Dies kennzeichnet auch die folgende Abbildung 4.5 genauer, in der in das Baumdiagramm der Elemente zusätzlich die Lokalisierungspfade eingetragen sind, wie sie vom Rechnungen-Element aus zu den einzelnen Elementen Kunde, Posten und Rechnung führen.
208
4. Schlüssel und Verweise
4
Abbildung 4.5: XPath-Ausdrücke im selector-Attribut
4. 2. 1. 2 Design-Alternative mit globalen komplexen Typen Für das zuvor gezeigte Beispiel sollen die gleichen Schlüssel nun für globale komplexe Typen definiert werden. Dabei bleiben die Lokalisierungspfade natürlich weiterhin erhalten, allerdings ist es schwieriger, bei der Entwicklung des Schemas diese Lokalisierungspfade zu bestimmen. Anstatt sich nun am Quelltext selbst zu orientieren, der mit Hilfe der Matrjoschka-Verschachtelungen arbeitet, muss man hier das entstehende Diagramm quasi im Kopf zeichnen und die entsprechenden Verschachtelungen über den Aufruf selbst ermitteln.
209
4. Schlüssel und Verweise
4
42_02.xsd: Modellierung mit Hilfe von globalen komplexen Typen
4
Abbildung 4.6: Modellierung mit Hilfe von globalen komplexen Typen
4. 2. 1. 3 Gültigkeitsbereiche von Schlüsseln Es wurde schon erwähnt, dass man unterschiedliche Gültigkeitsbereiche von Schlüsseln vorgeben kann bzw. dass diese wiederum von dem Element abhängen, in dem der Schlüssel definiert wurde. In den beiden vorherigen Beispielen handelte es sich sowohl im Matrjoschka-Design als auch im Beispiel mit globalen komplexen Typen um Schlüssel, die im Rechnungen-Element definiert wurden. Innerhalb seines Gültigkeitsbereichs galten diese Schlüssel, was bedeutete, dass sie jeweils für das gesamte Dokument galten. Möchte man das Dokument verlängern und alle Rechnungen eines Quartals erfassen, werden sich zwangsläufig die Kunden wiederholen, aber die Rechnungen selbst nicht. In diesem Fall müssen die Rechnungsnummern weiterhin innerhalb des Rechnungen-Elements eindeutig sein (hier tritt also keine Veränderung auf), die Schlüssel für die Kunden allerdings müssen in das Rechnung-Element platziert werden, damit sie für jede Rechnung als eindeutige Werte bzw. Fremdschlüsselwerte gekennzeichnet werden können.
211
4. Schlüssel und Verweise
4
Innerhalb des Dokuments ist es zwar so, dass aufgrund des Datenbankdesigns und der Extraktion der XML-Daten die Postennummern jeweils einzigartig sind, aber es besteht für eine Rechnung keine Notwendigkeit, dass die in ihr enthaltenen Postennummern wie 1, 2, 3 usw. nicht auch in anderen Rechnungen auftreten. Sie entsprechen dann sowohl einer Nummerierung als auch einem Schlüssel innerhalb der einzelnen Rechnung. In diesem Fall ist es möglich, den Schlüssel für die Postennummern innerhalb einer einzelnen Rechnung zu definieren, demnach genau eine Ebene tiefer als im vorherigen Beispiel. Für die Tarif-Elemente ergibt sich eine weitere Besonderheit, die bisher nicht berücksichtigt wurde. Zwar wird nicht die Tarifnummer in einem Nr-Attribut gespeichert (was allerdings kein großes Problem darstellen würde), sondern nur der Name, allerdings ist dieser Name für einen Monat bzw. innerhalb der einzelnen Rechnung (nicht allerdings innerhalb der Datenbank) durchaus auch wiederum ein Schlüssel, da für eine Rechnung nicht mehrfach ein Tarif abgerechnet wird. Dies alles ergibt eine Verlagerung einiger Schlüsselwerte in das Rechnung-Element, wodurch sich nicht nur die syntaktische Position der Schlüsseldefinitionen verändert, sondern darüber hinaus auch die Lokalisierungspfade andere sind, da sie jetzt vom Rechnung-Element aus gesehen werden müssen. Das Rechnung-Element dient jetzt nun als Container für die Schlüssel von Posten, Kunde und Tarif, was gleichzeitig bedeutet, dass die Einzigartigkeit der jeweiligen Werte nur für eine Rechnung und nicht innerhalb des gesamten Dokuments geprüft wird. Diese Konstruktion findet sich im nachfolgenden Dokument, in dem sowohl die einzelnen Schlüssel noch einmal hervorgehoben sind als auch die wertstiftenden Elemente und Attribute.
212
4. Schlüssel und Verweise
213
4. Schlüssel und Verweise
42_03.xsd: Unterschiedliche Gültigkeitsbereiche von Schlüsseln
4
In Abbildung 4.7 sieht man deutlich die unterschiedlichen Lokalisierungspfade und ihre ebenfalls unterschiedlichen Ursprünge im Rechnungen- und Rechnung-Element. Über diese Ursprünge legt man fest, in welchem Gültigkeitsbereich die Schlüssel geprüft und auf auftretende Wertduplikate hin überwacht werden.
Abbildung 4.7: Unterschiedliche Gültigkeitsbereiche von Schlüsseln
4. 2. 2. Eindeutigkeitsbeschränkung über Als weiteres Mittel für die Bestimmung und Erzeugung von Schlüsselfeldern wurde bereits zuvor die Technik über die Schema-Komponente eingeführt. Im Gegensatz
214
4. Schlüssel und Verweise
zu darf ein Feld, das für einen Schlüssel verwendet wird, auch fehlen, d. h., ganz einfach nicht im Dokument vorhanden sein. Wenn es aber vorhanden ist, dann müssen für dieses Feld die Werte innerhalb des Gültigkeitsraums des Schlüssels einzigartig sein. Während demnach auf Einzigartigkeit und Existenz hin prüft, reduziert sich das Prüfungsschema von auf die Einzigartigkeit. 4. 2. 2. 1 Definition von Eindeutigkeit Es bieten sich unterschiedliche Möglichkeiten, Eindeutigkeiten für das oben abgedruckte Dokument zu formulieren. Die beiden interessanten Varianten seien hier kurz erläutert. Die allgemeine Syntax für die Definition einer Eindeutigkeit lautet: Inhalt: (annotation?, (selector, field+))
Die Syntax besteht aus einem name-Attribut, in dem für die Eindeutigkeitsbeschränkungen innerhalb des Dokuments ein eindeutiger Name vergeben wird, über den die Eindeutigkeitsbeschränkung in einem Verweis auch angesprochen werden kann. Für die eigentliche Definition des Wertes der Eindeutigkeitsbeschränkung kommen zwei spezielle Elemente zum Einsatz: und , wobei nur ein -Element, allerdings mehrere -Elemente zulässig sind. Im -Element befindet sich ein XPath-Ausdruck, der ausgehend vom Element, in dem die Eindeutigkeitsbeschränkung definiert wird, das Element angibt, in dem die Eindeutigkeitsbeschränkung zu finden ist. Mit Hilfe des -Elements legt man dann fest, ob sich dieser Wert in einem Attribut, im Textknoten dieses Elements oder in einem anderen Element befindet. Im letzten Fall wird der Textknoten automatisch ausgewählt. Für Attribute ist nur die Angabe im -Element zulässig. Beide zusammen sind also erforderlich, um tatsächlich auch den Wert und die Position zu ermitteln, der für die komplette Angabe der Eindeutigkeitsbeschränkung notwendig ist. Für die Darstellung des Einsatzes von mag ein neues Beispiel dienen, das gleichzeitig auch die Syntax von mehreren Feldern und einen Vergleich zwischen dem Schlüssel- und dem Einzigartigkeitskonzept darstellt. Es handelt sich um ein Dokument, das
215
4
4. Schlüssel und Verweise
die einzelnen Anrufe enthält, aus denen sich z. B. die Rechnungen um Umsätze der RuhrFon GmbH ermitteln lassen. Dabei regelt ein Typ -Attribut, um welchen Anruftyp es sich handelt. Bei einem privaten Telefongespräch sind im Kunde-Element die beiden Elemente Vorname und Nachname sowie ein optionales Anrede-Attribut enthalten, während bei einem Telefonat von einem Geschäftskunden nur ein Name-Element und kein Anrede-Attribut vorhanden ist. Auf die Gestaltung solcher optionaler Felder ist ja gerade die Einzigartigkeitsbeschränkung aufgebaut, weil im einen oder anderen Fall jeweils Felder fehlen bzw. auch zugelassen werden sollen oder eine Namensangabe fehlt oder noch unvollständig ist. Wichtig ist dagegen die Kundennummer. Darüber hinaus liegen natürlich auch wieder für alle anderen Nr-Attribute sowie den Tarifnamen Schlüsselelemente und -attribute vor.
4
Martin Fulland Lucie Folkers Mittagspause 1 37
42_04.xml: Anrufe mit verschiedenen Inhalten
Da man sowohl bei einer Auswahl über als auch bei einer Kombination von Elementen min minOccurs=“0“ gerade nicht davon ausgeht, dass die Elemente auch immer vorhanden sind, auf die sich der Schlüssel beziehen soll, muss im Gegensatz zum Nr-Attribut des Kunde-Elements hier eine Einzigartigkeitsbeschränkung verwendet werden, die ein Fehlen der Elemente Vorname, Nachname und Name zulässt. Für die Angabe mehrerer Felder, aus denen sich ein Schlüssel oder eine Einzigartigkeitsbeschränkung zu-
216
4. Schlüssel und Verweise
sammensetzen kann, verwendet man ganz einfach mehrere -Elemente innerhalb eines - oder -Containers. Dabei werden die Felder in einem Schlüssel addiert bzw. über eine logische UND -Verknüpfung zusammengefasst, während bei einer Einzigartigkeitsbeschränkung wegen der Optionalität der Felder eine ODER-Verknüpfung stattfindet. Für den konkreten Fall ergibt sich also für das Element Kunde eine Einzigartigkeitsbeschränkung auf die Felder Vorname, Nachname und Name, aber eine Schlüsselbeschränkung auf das Attribut Nr, das in jedem Fall enthalten sein muss, um den Anruf einem Kunden zuordnen zu können. Gleiches gilt für das Element Tarif, sein eigenes Nr-Attribut und für den Anruf selbst. Der Name eines Tarifs kann ebenso als Schlüssel verwendet werden, da er für einen konkreten Zeitraum, der selbst wiederum über den Anrufzeitraum abgefragt werden könnte, eindeutig ist.
217
4
4. Schlüssel und Verweise
42_03.xsd: Eindeutigkeit und Schlüssel im Vergleich
218
4. Schlüssel und Verweise
4 Abbildung 4.8: Anruf mit verschiedenen Inhalten
4. 2. 2. 2 Verwendung der Einzigartigkeitsbeschränkung bei Auswahl Wie zuvor kurz angedeutet, kann man die Kind-Elemente von Kunde mit Hilfe einer Auswahl definieren, um die Zugehörigkeit von Vorname und Nachname zueinander sowie ihre Reihenfolge und das alternative Auftreten von den Elementen für den Privatkunden und Name für den Geschäftskunden zu trennen. Es kann die gleiche Eindeutigkeitsbeschränkung wie zuvor verwendet werden, wobei nun aber das Inhaltsmodell viel genauer angibt, welche Elemente dennoch gemeinsam auftreten sollen und in welcher Häufigkeit dies geschehen soll. Während man zuvor gar nicht umhin kam, die Elemente als optional zu deklarieren, sind nun die für den Rechnungsversand durchaus benötigten Namensfelder jeweils einmal verpflichtend.
219
4. Schlüssel und Verweise
...
...
4
42_04.xsd: Alternative Modellierung mit Auswahl
Abbildung 4.9: Alternative Modellierung mit Auswahl
4. 2. 3. Verweise auf Schlüssel und Eindeutigkeitsbeschränkungen Um Verweise auf Schlüssel oder Eindeutigkeitsbeschränkungen einzurichten, verwendet man das Element , das sich mit seinem refer-Attribut auf genau einen im Dokument definierten Schlüssel bezieht. Die allgemeine Syntax lautet wie folgt:
220
4. Schlüssel und Verweise
Inhalt: (annotation?, (selector, field+))
Auch dieses Element dient als Container für und , wobei diese beiden Elemente jeweils in einem XPath-Ausdruck dasjenige Element, den Textknoten oder das Attribut auswählen, das den Inhalt für den Verweis benötigt. Hier trägt man also die Verweisquelle ein, während das Verweisziel im refer-Attribut untergebracht wird. Für das vorliegende Beispiel der Rechnung liegt ein Verweis von jedem Posten zum Element Rechnung vor, das auch gleichzeitig sein Eltern-Element ist. 6.38 5 Frühstück 0.85
Mittagspause 1.51 ... 42_01.xml: Verweise in einem Dokument
Für die der Schlüssel und Verweise benötigt man zwei Schlüssel für das Element Rechnung, weil man die Gültigkeit einer Rechnungsnummer nicht dokumentweit, sondern nur innerhalb des Gültigkeitsbereichs eines Rechnung-Elements prüfen möchte. Der Unterschied
221
4
4. Schlüssel und Verweise
4
besteht darin, dass bei einer dokumentweiten Prüfung, die über einen Schlüssel für das Element Rechnung im Element Rechnungen eingerichtet wird (was bisher der Fall war), jede Rechnungsnummer gültig ist, die im Dokument erscheint. Dies ist natürlich genau das, was im Dokument nicht geprüft werden soll. Vielmehr möchte man verhindern, dass innerhalb einer Rechnung eine andere Bezugsnummer als die aktuelle Rechnungsnummer verwendet wird. Dafür benötigt man einen eigenen Schlüssel, der für das Element Rechnung mit seinem Nr-Attribut als Schlüsselwert erstellt wird, der nur für den Verweis gültig ist und sonst keine weitere Bedeutung hat. Dies liegt daran, dass die dokumentweite Prüfung der Rechnungsnummer für die Rechnung im Element Rechnungen liegt, und natürlich nicht in das Element Rechnung umgelagert werden kann. Dies würde nämlich bedeuten, dass für jede Rechnung geprüft wird, ob ihre Nummer einzigartig ist. Und das wäre sie sogar, wenn alle Rechnungen die gleiche Nummer aufwiesen, weil der Gültigkeitsbereich dieses zusätzlichen Schlüssels nur für das Element Rechnung, nicht aber für das gesamte Dokument gilt. ... ... ...
222
4. Schlüssel und Verweise
...
4
42_05.xsd: Verweise auf Schlüssel
Abbildung 4.10: Verwendung von Verweisen
223
4. Schlüssel und Verweise
Abbildung 4.10 soll noch einmal verdeutlichen, wozu die beiden Schlüsseldefinitionen für das Element Rechnung dienen. Mit RSchluessel1, also dem Schlüssel im Element Rechnungen, legt man eine dokumentweite Prüfung fest, damit keine doppelten Rechnungsnummern entstehen. Mit RSchluessel2 dagegen richtet man nur das Verweisziel für das Element Posten ein, damit eine Prüfung der Rechnungsnummer innerhalb einer Rechnung und nicht etwa innerhalb des gesamten Dokuments stattfindet.
4
224
Auslagerung und Wiederverwendung
5. Auslagerung und Wiederverwendung
5. Auslagerung und Wiederverwendung Um die Pflege von größeren Schema-Dokumenten und umfangreichen Datenstrukturen zu ermöglichen, bedient man sich gängiger Auslagerungstechniken, wie sie auch in verschiedenen anderen Programmiersprachen erhältlich sind. Dadurch kann man größere Projekte bzw. größere Datenstrukturen in kleinere Einheiten zerlegen und sie modular zusammensetzen.
5
In den zurückliegenden Beispielen ergab sich keine Notwendigkeit, geschaffene Strukturen wie z. B. Datentypen in eine eigene Datei auszulagern und diese Datei in andere SchemaDokumente einzubinden. In größeren Anwendungen sind dagegen die jeweiligen Möglichkeiten der Auslagerung und Wiederverwendung von Datentypen, komplexen Typen oder gar ganzen Schema-Bereichen sehr wohl interessant. Dabei unterscheidet man zwei grundsätzliche Situationen. In der ersten hat man es mit einer Vielzahl von kleinen oder großen Schema-Dokumenten zu tun, die alle auf eine gemeinsame Datenbasis zurückgreifen. Es könnte z. B. die Datenstruktur für einen Kunden sein, der für den Datenaustausch komplett aus einer Datenbank gelesen und in sehr flacher Form über Kind-Elemente oder auch Attribute übertragen wird. In dieser Situation würde XML solche Formate wie kommagetrennte Werte ersetzen. Besteht für ein anderes Dokument bereits ein Schema-Dokument, in dem alle fünfzig Spalten, aus denen die entsprechende Kunden-Tabelle besteht, aufgenommen und mit passenden Datentypen versehen sind, so wäre es natürlich überaus vorteilhaft, diese fünfzig Eigenschaften in Form von Attributen oder Elementen nicht erneut deklarieren oder von der einen in die andere Datei kopieren zu müssen. Viel besser wäre es, die Kundendatenstruktur in eine Datei auszulagern, diese Datei zu referenzieren und sie in der neuen Datenaustauschdatei zu verwenden. In der zweiten Situation sind es nicht die vielen Elemente oder Attribute, die zu modellieren sind, sondern es handelt sich vielmehr um wenige Strukturen wie Datentypen, die immer und immer wieder in Dokumenten auftauchen. Solche Eigenschaften können spezielle Fassetten mit Unter- oder Obergrenzen sein, die wie magische Werte am besten nicht in
226
5. Auslagerung und Wiederverwendung
Anwendungen auftauchen oder – wenn es sich nicht vermeiden lässt – zentral gespeichert werden sollten, um sie leicht zu ändern und keine ungewollten Nebeneffekte zu erzielen. Hier ist es weniger die Anzahl an ausgelagerten Einheiten, sondern die Vielzahl an Aufrufen, die eine Auslagerung einer auch kleineren Mengen an Datentypen, Elementen, Attributgruppen etc. interessant macht.
5. 1. Inklusion Die Einbindung ist aus verschiedenen Programmiersprachen und auch im XML-Bereich bei XSLT bekanntes Verfahren der Auslagerung und Wiederverwendung, die auch in XML Schema genutzt wird. Eine Datei enthält die benötigten Inhalte, ohne dabei selbst eine in sich abgeschlossene Schema-Datei sein zu müssen. Dies heißt nicht, dass sie nicht wohlgeformt ist, sondern nur, dass sie für sich alleine kein Dokument validieren können muss. Dies ist insbesondere bei solchen Dateien der Fall, die nur Datentypen oder globale Elemente ohne Wurzelelement enthalten und daher tatsächlich nur Teilbereiche eines anderen SchemaDokuments aufweisen. Diese Dateien lassen sich in anderen XML Schema-Dokumenten auf oberster Ebene durch das Element aufrufen und stellen ihre Inhalte der aufrufenden Datei zur Verfügung, als wären die Inhalte direkt in der Datei als oberste bzw. globale Elemente deklariert und die Datentypen ebenfalls global definiert worden. Genauso wie bei XSLT gibt es auch in XML Schema die Möglichkeit, Inhalte aus inkludierten Dateien zu überschreiben, wobei allerdings ein Mechanismus in XML Schema zum Einsatz kommt, der sich nicht durch die Unterscheidung zwischen Inklusion und Import hervorhebt, sondern durch das Element und der Angabe, welche neuen Eigenschaften ein eingefügtes Element besitzen soll. Die allgemeine Syntax der Einbindung lautet: Inhalt: (annotation?)
227
5
5. Auslagerung und Wiederverwendung
5. 1. 1. Einfache Wiederverwendung Die folgende Datei soll als Beispiel für den Einsatz der Inklusion dienen. Sie enthält eine variierte Umsatzübersicht der einzelnen Telefontarife, wobei dieses Mal der kleinste und größte Umsatz bei einem Gespräch sowie der Durchschnittsumsatz eines Telefonats in diesem Tarif gespeichert wird. Zudem enthält es die geführten Telefonate zu diesem Tarif und die Gesamtanzahl der Telefonate im Jahr.
Abendessen
5
0.01
1.17 0.36 967 968111 ... 51_01.xml: Umsatzwerte mit unterschiedlichen Datentypen
Die ausgelagerte Datei enthält für diese Auswertung wie für viele andere mit ähnlicher oder auch gleicher Ausrichtung eine Auswahl an verschiedenen Datentypen, die mehrfach eingesetzt werden könnten. Wie man an der Datei gut erkennen kann, ist sie zwar eine wohlgeformte und gültige XML Schema-Datei, aber sie wäre nicht in der Lage, ein Instanzdokument zu validieren. Hierzu fehlt ihr nicht nur ein Wurzelelement, sondern überhaupt wenigstens ein Element, in dem Inhalte mit den definierten Datentypen gespeichert werden könnten. Inhaltlich enthält es die Angabe eines Datentyps für Preise mit zwei Dezimalstellen und einer maximalen Länge von fünf sowie einer Untergrenze von 0. Dazu kommt ein Datentyp für die verschiedenen Bezeichnungen wie den Tarifnamen oder den Tariftyp als normalisierte Zeichenkette mit Mindestlänge 1 sowie ein Datumstyp für das Jahr mit dem Jahr der Unternehmensgründung als Untergrenze.
228
5. Auslagerung und Wiederverwendung
…
5
51_01typen.xsd: Schema-Dokumente mit Datentypdeklarationen
Die eigentliche Schema-Datei, die das gesamte Instanzdokument validieren kann, wenn die Bezüge zu den gerade beschriebenen Datentypen aufgelöst werden können, enthält für die Verwendung der ausgelagerten Strukturen einen Link zu dieser Datei innerhalb des -Elements in seinem schemaLocation-Attribut. Es enthält einen relativen oder absoluten Pfad zu der jeweiligen Datei, die ihre Inhalte genauso im aufrufenden Dokument zur Verfügung stellt, wie sie im ausgelagerten Dokument vorliegen. Weil das -Element ein direktes Kind-Element vom schema-Element ist, kann man sich die Übernahme der ausgelagerten Strukturen so vorstellen, als ob an der Stelle des include-Elements eine Ersetzung durch die in der inkludierten Datei enthaltenen Inhalte stattfinden würden, d. h., als ob eine Ersetzung des Elements durch die inkludierten Inhalte geschähe. Daher besteht die Möglichkeit, diese Inhalte in Form von Datentypreferenzen einfach im Dokument zu verwenden.
229
5. Auslagerung und Wiederverwendung
...
5
51_01.xsd: Import und Verwendung von Datentypen
230
5. Auslagerung und Wiederverwendung
Abbildung 5.1: Struktur der Umsatzübersicht
Die Grafik soll das sehr einfache Prinzip der Inklusion noch einmal veranschaulichen. Genauso wie in einer Programmiersprache, in der als einfachste Auslagerungstechnik nicht die Verwendung von Klassen zum Einsatz kommt, sondern gerade die Inklusion anderer Dateien mit Programmmodulen, Funktionen etc., lässt sich die Inklusion in XML Schema deuten. Die in der ausgelagerten Datei gespeicherten Inhalte, die selbst und alleine kein Instanzdokument validieren könnten und nur aus einer Reihe von Datentypdefinitionen bestehen, gelangen über die Inklusion bzw. genauer über das include-Element in die aufrufende Datei und lassen sich dort genauso aufrufen wie alle ihre anderen, global deklarierten Strukturen.
231
5
5. Auslagerung und Wiederverwendung
5
Abbildung 5.2: Prinzip der Inklusion und Wiederverwendung
232
5. Auslagerung und Wiederverwendung
5. 1. 2. Wiederverwendung mit Redefinition Während bei der Inklusion keine Ableitung zulässig ist und damit die gegebenen Strukturen stets übernommen werden müssen, existiert für die Fälle, in denen Änderungen an den eingefügten Inhalten vorgenommen werden sollen, eine eigene Schema-Komponente. Sie heißt treffenderweise redefine und gestattet die beiden gängigen Ableitungen durch Erweiterung und durch Einschränkung. Die allgemeine Syntax hat die Form:
5
Inhalt: (annotation | (simpleType | complexType | group | attributeGroup))*
5. 1. 2. 1 Ableitung durch Erweiterung Wie immer bei Ableitungen lässt sich unterscheiden, ob eine Datenstruktur oder ob gegebene Eigenschaften erweitert oder verringert werden. Daher verwundert es nicht, dass bei der Redefinition auch eine Ableitung durch Erweiterung und eine durch Einschränkung beschrieben werden kann. Zunächst wird die Ableitung durch Erweiterung dargestellt, bei der ein globaler komplexer Typ mit einigen Kind-Elementen verwendet wird, in dem Verweise auf ebenfalls in dieses Dokument eingebundene Datentypen zu finden sind. Auf die Einfügung in dieser Datei, die auf die gerade erzeugten Datentypen verweist, wird später in einem eigenen Abschnitt eingegangen. Für das aktuelle Beispiel ist nur wichtig, dass natürlich auch mehrstufige Verweise möglich sind und dass diese Inhalte dann auch in jenem Dokument, das ein Dokument mit Inklusion aufruft, ebenfalls verfügbar sind.
233
5. Auslagerung und Wiederverwendung
51_02komplexeTypen.xsd: Deklaration eines ausgelagerten komplexen Typs
5 Abbildung 5.3: Ausgelagerter komplexer Typ
In der aufrufenden Datei referenziert man dann wie zuvor in einem include-Element die gerade abgedruckte Datei mit dem globalen komplexen Typ, der die Elemente für Minimal-, Maximal- und Durchschnittsumsatz pro Telefontarif enthält. Dies genügt allerdings für das aktuell zu modellierende Dokument nicht, weil noch zwei absolute Werte für die Gesamtanzahl der Anrufe und die Gesamtzahl der Anrufe pro Tarif jeweils zum Vergleich übernommen werden soll. Durch die Ableitung durch Erweiterung schließt man die genannten Elemente an die Reihenfolge der ersten drei Elemente im globalen komplexen Typ an. Dies entspricht exakt der Standardfunktions- und -vorgehensweise der schon zuvor beschriebenen Ableitung durch Erweiterung. Die neuen Elemente werden nicht vor oder zwischen die bereits existierenden Elemente geschoben, wofür auch syntaktisch keine Angaben in Form von entsprechenden Schema-Komponenten zur Verfügung stünden, sondern an die bestehenden angehängt.
234
5. Auslagerung und Wiederverwendung
...
5
51_02.xsd: Ableitung durch Erweiterung bei Redefinition
Abbildung 5.4: Ableitung durch Erweiterung
235
5. Auslagerung und Wiederverwendung
Abbildung 5.4 verdeutlicht die Entsprechung der Ableitung durch Erweiterung im Standardfall und der hier vorgestellten, bei der die Basis einer Datenstruktur in einem globalen komplexen Typ liegt. Handelte es sich nicht um einen globalen komplexen Typ, sondern um einen einfachen Typ, würde es sich genauso verhalten. In diesem Fall stünde der Aufruf des einfachen Typs in einem simpleContent-Container, der z. B. zusätzlich ein Attribut enthalten würde, das ja bei der Ableitung durch Erweiterung in einem einfachen Typ bzw. in einem Inhaltscontainer eingefügt werden kann. Eine übersichtliche Darstellung der Mechanismen der Ableitung durch Erweiterung zeigt Abbildung 5.5. Sie zeigt, wie die Strukturen in der eingebundenen Datei um weitere Elemente bzw. eine Strukturerweiterung in der aufrufenden Datei ergänzt werden. Prinzipiell handelt es sich dabei um ein Analogon der Syntax, falls die eingefügte Struktur direkt im Dokument gespeichert wäre.
5
Abbildung 5.5: Ableitung durch Erweiterung bei Redefinition
5. 1. 2. 2 Ableitung durch Einschränkung Der zweite zu behandelnde Fall ist die Ableitung durch Einschränkung, bei der eine Datenstruktur um Elemente, Attribute oder Eigenschaften eines Datentyps verringert wird. Die soll erneut bei einem globalen komplexen Typ geschehen, der demjenigen aus dem
236
5. Auslagerung und Wiederverwendung
vorherigen Abschnitt ähnelt. Nun enthält er mehr Kind-Elemente wie die gerade bei der Ableitung durch Erweiterung angefügten Gesamt- und Einzelzahlen der Anrufe pro Tarif und den gesamten Umsatz sowie den häufigsten zu bezahlenden Preis, d. h., den Modalwert.
5
51_03komplexeTypen.xsd: Ausgelagerter komplexer Typ
Abbildung 5.6: Ausgelagerter komplexer Typ
Soll nun der Modalwert nicht mehr im Instanzdokument auftreten dürfen, handelt es sich erstens um eine Ableitung durch Einschränkung und zweitens um eine komplette Neudefinition der vorhandenen Datenstruktur. Wie schon für die ansonsten übliche Ableitungs-
237
5. Auslagerung und Wiederverwendung
technik durch Einschränkung gezeigt, so gilt auch hier, dass zwar über das base-Attribut im restriction-Container-Element eine Verbindung zu einem bereits bestehenden globalen komplexen Typ (oder auch einem anderen Element) existiert, dass diese aber nicht tatsächlich überprüft wird. Es handelt sich daher um die gleiche lockere Angabe wie zuvor, sodass sie eigentlich auf eine Dokumentationsnotiz herabgestuft wird. Im aktuellen Beispiel bezieht man sich daher auf den zuvor definierten globalen komplexen Typ SummeTyp, gibt dann allerdings seine komplette Eigenschaften an und nicht nur die Tatsache, dass das Element Modus nicht verwendet werden darf. Dies ist ein Umstand, der bereits zu einiger Kritik bei der Vorstellung der allgemeinen Ableitungsstrukturen berechtigte und auch hier wieder für Trübsal sorgt.
5
Bei anderen Strukturen, die aus Platzgründen nicht mit einem eigenen Beispiel abgedruckt werden sollen, verhält es sich natürlich analog, d. h., die eingeschränkten Inhalte müssen komplett angegeben werden. ...
238
5. Auslagerung und Wiederverwendung
51_03.xsd: Ableitung durch Einschränkung
5 Abbildung 5.7: Ableitung durch Einschränkung
Abbildung 5.7 zeigt zwar, dass eine syntaktische Verbindung zwischen dem abgeleiteten und dem in einer externen Datei deklarierten Typ besteht, sie soll allerdings auch verdeutlichen, dass dies nicht mehr als eine lose Referenz ist. Die neuen und damit im Instanzdokument gültigen Inhalte müssen komplett neu angegeben werden. Attribute nehmen eine kleine Sonderrolle ein, wenn sie in Form einer Attributgruppe ausgelagert waren und nun mit einer Ableitung durch Einschränkung redefiniert werden sollen. Während Attribute, die zu einem globalen komplexen Typ oder einem einfachen Typ gehören, unverändert in die Redefinition übernommen werden, wenn sie nicht erwähnt werden, verhält es sich bei Attributgruppen gerade anders herum. Alle Attribute, die im Instanzdokument verwendet werden dürfen (entweder optional oder verpflichtend) müssen komplett in der Redefinition genannt werden. Dies entspricht dem Vorgehen für Elemente in einem globalen komplexen Typ.
239
5. Auslagerung und Wiederverwendung
5 Abbildung 5.8: Ableitung durch Einschränkung
Beispielhaft ist die folgende Datei mit einer Attributgruppe, die einige charakterisierende und typisierende Attribute für verschiedene denkbare Elemente enthält.
51_04attribute.xsd: Ausgelagerte Attributgruppe
240
5. Auslagerung und Wiederverwendung
In der aufrufenden Datei nun redefiniert man diese Attributgruppe so, dass nur noch das Attribut Nr verpflichtend auftaucht, wohingegen alle anderen nicht mehr verwendbar sind, weil sie nicht erwähnt werden. ...
5
51_04.xsd: Ableitung durch Einschränkung bei Attributgruppe
5. 1. 3. Mehrstufige Inklusion und Namensräume Während die Definition des globalen komplexen Typs im Beispiel bei der Ableitung durch Erweiterung keine Besonderheiten bietet, weil sie natürlich genau denselben Syntaxregeln wie bei einer Deklaration innerhalb des gleich folgenden Schema-Dokuments folgt, ist die Inklusion der zuvor erzeugten Datentypen durchaus bemerkenswert. So zeigt dieses Beispiel sehr deutlich auch die Verwendung der Inklusion in inkludierten Dateien. Innerhalb eines einzigen Namensraums (im Gegensatz zum import-Element des nächsten Abschnitts!) lässt sich das include-Element für die Übernahme von Informationen aus anderen Dateien nutzen. Eine Begrenzung der inkludierten Dateien besteht grundsätzlich nicht – so sagt es zumindest die Spezifikation. Die einzige Einschränkung besteht darin, dass
241
5. Auslagerung und Wiederverwendung
entweder gerade der gleiche Zielnamensraum im targetNamenspace-Attribut angegeben sein muss oder gar keiner, wobei dann der Zielnamensraum des aufrufenden Dokuments zugrunde gelegt wird. Damit ist das Dokument gemeint, das die anderen Dokumente inkludiert. Sobald ein Dokument ohne angegebenen Zielnamensraum in ein Dokument eingefügt wird, erhält es also den Zielnamensraum des einfügenden Dokuments, wozu auch etwaige Präfixe für die Adressierung von Elementen und Attributen zählen. Auf diese Präfixe kann man dann bei der Verwendung von eingefügten Strukturen zurückgreifen. Hier kann es zu Schwierigkeiten bei der Verwendung von Schlüsselangaben über unique kommen, da die entsprechenden Referenzen in den xpath-Attributen der Elemente selector und field nicht mehr korrekt aufgelöst werden können.
5
Theoretisch ist die mehrfache Einfügung von Dokumenten keine Schwierigkeit, zumindest findet man in der Spezifikation zu diesem Punkt kein Verbot. Allerdings fehlt nicht der Hinweis, dass im Sinne einer effizienten und schnellen Verarbeitung der Dokumentangabe eine mehrfache Verwendung eines Dokuments über eine Inklusion zu vermeiden sei. Grundsätzlich stellt es auch keine Hürde dar, anstatt eines mehrfachen Aufrufs in Dokument A nur einen einzigen Aufruf zu platzieren. Schwieriger hingegen wird es hingegen, wenn Dokument A ein Dokument B und ein Dokument C aufruft, wobei Dokument C ebenfalls Dokument B aufruft, sodass es einmal direkt und einmal indirekt in das Dokument A eingebunden wird. Im Standardfall ist ein solches Vorgehen für den Parser keine unmöglich zu lösende Aufgabe. Eine solche Situation sollte allerdings in den meisten Fällen durch einen Verzicht auf den Aufruf von Dokument C direkt in Dokument A vermeidbar sein. Etwaige Referenzen auf Strukturen in C sind dann zwar nur gültig, wenn tatsächlich in Dokument A der Verweis auf B und in diesem der Verweis auf C erfolgt, aber sobald dieser Zustand eingerichtet ist, sind die jeweiligen Bezüge wieder gültig. Der gerade präsentierte Zustand macht nun den Aufruf von Inhalten im mehrfach eingebundenen Dokument von Aufrufen in anderen Dokumenten und damit von Zuständen in anderen Dokumenten abhängig, was natürlich im schlimmsten Fall zu einem Kontrollverlust des entsprechenden Schema-Autors bei Team-Arbeit oder verteilter Arbeit führen könnte. Nur um dieses unschöne Problem aus der Welt zu schaffen, ist eine mehrfache Einfügung gültig, und sie sollte auch nur in solchen Fällen (also zur Verhinderung größeren Übels) zum Einsatz kommen.
5. 2. Import von Strukturen Wie schon oben erwähnt, unterscheidet sich der Import von der Inklusion nicht etwa dadurch, dass importierte Strukturen geändert werden können und eingebundene hingegen
242
5. Auslagerung und Wiederverwendung
nicht, wie es bei XSLT für die beiden Elemente xsl:include und xsl:import der Fall ist, sondern in der Verarbeitung von Namensräumen. Die spielen für XSLT zwar auch eine wichtige Rolle, werden dort aber auf die Auswahl und Adressierung von Knoten reduziert. In XML Schema sind Namensräume allerdings in zwei unterschiedlichen Dimensionen wichtig: ●●
Zum einen handelt es sich bei einem XML Schema-Dokument um ein gültiges XMLDokument, das seine eigenen Elemente, Attribute und jeweilige Inhaltsmodelle besitzt. Dies bedeutet, dass über den Namensraum xs die entsprechenden Elemente und Attribute sowie ihre Eigenschaften bekannt sind. Weil in den XML Schema-Elementen auch immer die Verwendung von Attributen aus einem anderen Namensraum gestattet ist, ist der Einsatz von Namensräumen für die Erstellung der Schema-Dateien selbst und der Bezüge zu Attributen anderer Namensräume für die Validierung der Schema-Datei selbst wichtig.
●●
Zum anderen gibt ein Schema-Dokument die Regelungen für die Verwendung von Elementen und Attributen in einem XML-Instanzdokument bzw. XML-Datenstrom vor. Dieser wiederum kann selbst aus einem bestimmten Namensraum seine Elemente und Attriute beziehen. Aufgabe der Schema-Datei ist es in diesem Fall, die Qualifizierung der jeweiligen Komponenten zu steuern bzw. den Namensraum anzugeben, der für diese Datei insgesamt oder für einzelne Elemente gültig ist.
Für die Verwendung von Namensräumen im Zusammenhang mit dem Import von SchemaStrukturen aus anderen Schema-Dateien ist der Import-Mechanismus von XML Schema einzusetzen und nicht die Inklusion aus dem vorherigen Abschnitt. Ein Schema-Dokument enthält auf der obersten Ebene entweder eine Namensraumangabe oder explizit keine. Das Fehlen dieser Information bedeutet also ausdrücklich, dass kein Namensraum für die Verwendung der definierten Strukturen zu verwenden ist. Der entsprechende Namensraum wird mit dem Begriff „Zielnamensraum“ bezeichnet und im targetNamespace-Attribut des schema-Elements angegeben. Entstammen Strukturen einem anderen Namensraum als dem des im importierenden Schema-Dokuments angegebenen bzw. dort fehlenden, dann kann auf diese Strukturen nur über den Import verwiesen werden. Die Schema-Komponente import gibt einen Namensraum an, der in einer externen Datei benutzt werden soll und deren Inhalte in der aufrufenden Datei bereitgestellt werden sollen. Der im Attribut namespace angegebene Wert legt fest, dass das importierte Schema-Dokument Referenzen auf diesen Namensraum enthält. Durch die Angabe wird zudem festgelegt, dass die importierten Strukturen ihren Namensraum behalten und also nicht Teil des Namensraums werden. Fehlt also diese Angabe, so übernehmen sie den Namensraum, unter dem sie ursprünglich erstellt wurden, nicht. Der im Attribut schemaLocation
243
5
5. Auslagerung und Wiederverwendung
angegebene Wert enthält dann die Angabe, an welcher Stelle (Webseite, Dokument) das Schema-Dokument zu finden ist, das sich auf diesen Namensraums bezieht. Es enthält also – vereinfachend gesagt – die Datei, die eingebunden werden soll. Die allgemeine Syntax hat die Form:
Inhalt: (annotation?)
5
Im Vergleich zu den Techniken der Redefinition und der Inklusion entspricht der Import also nicht dem so genannten Chamäleon-Design. Sein Name soll daran erinnern, dass bei der Redefinition und bei der Inklusion die übernommenen Strukturen in den Namensraum der aufrufenden Datei aufgehen und sich wie ein Chamäleon an den Zielnamensraum dieser Datei anpassen.
5. 2. 1. Grundprinzip des Imports Zunächst soll an einem einfachen Beispiel die grundsätzliche Funktionsweise des ImportMechanismus bei der Dokumentmodellierung dargestellt werden. Dazu geht man zunächst von einem XML-Instanzdokument aus, in welchem die Verwendung von Namensräumen sicherlich bereits bekannt ist. Das folgende Dokument speichert Umsatzinformationen zu jedem Tarif, wobei jeweils Tarif-Informationen von ihren Umsatzinformationen innerhalb jeweils einem Eltern-Element Tarif und Summe untergebracht sind, die beide zusammen Kind-Elemente von einem Umsatz-Element sind. Als Namensraum ist in diesem Dokument der Namensraum da enthalten, der sich auf einen Dienstleister der RuhrFon GmbH bezieht. Inhaltlich bzw. mit Blick auf das Buchbeispiel verhält es sich so, dass dieser Dienstleister die Analysen zum Kundenverhalten etc. ausführt und entsprechende Berichte in XML-Form an die RuhrFon GmbH übermittelt. Dieses Dokument entstammt also komplett dem Namensraum des Dienstleisters. Die einzelnen Elemente müssen nicht extra mit dem vorhandenen Namensraum ausgezeichnet werden, da er im Wurzelelement angegeben ist.
244
5. Auslagerung und Wiederverwendung
Abendessen p
2003
347.92 74505.9
363230.71 .1
5
...
52_01.xml: Einsatz von Namensräumen
In einem Schema-Dokument legt man globale komplexen Typen und Datentypen für die Verwendung in unterschiedlichen Schema-Dateien fest, die jeweils verschiedene Analysen und Berichte charakterisieren. Auch hier befindet sich der gleichnamige Namensraum. Er wird wie zuvor über die Standardnamensraumangabe in XML mit Hilfe des xmlns-Attribut und einer passenden URI sowie mit Hilfe des targetNamespace-Attribut festgelegt. Hier erkennt man nun auch sehr deutlich, dass der Namensraum xs ebenfalls direkt für das gesamte schema innerhalb des schema-Elements mit Hilfe des xmlns-Attributs festgelegt wird und nun in diesem Dokument einmal der Namensraum xs und einmal der Namensraum da existiert, wobei letzterer auch der Namensraum für die Instanzdokumente sein soll. Das Dokument referenziert auf diesen Namensraum für jede Schema-Komponente mit Hilfe des angegebenen Präfixes xs. Weil man in einem Dokument mit Zielnamensraumangabe auf globale Strukturen verweist, wie es hier mit einfachen Typen geschieht, müssen diese sowohl in der aktuellen Datei als auch in der importierenden Datei qualifiziert werden. Durch die Angabe, dass Elemente und Attribute per Standard unqualifiziert verwendet werden können, bezieht man sich auf das Instanzdokument. Hier können Elemente unqualifiziert auftreten, wobei sie dennoch einem Namensraum zugehören, der im Wurzele-
245
5. Auslagerung und Wiederverwendung
ment mit dem xmlns-Attribut angegeben ist und sich mit dem Zielnamensraum deckt. Die Attribute elementFormDefault und attributeFormDefault ersetzen global die für die attribute- und element-Elemente zugehörigen form-Attribute, in denen individuell für jedes Element und jedes Attribut angegeben werden kann, ob es im Instanzdokument qualifiziert oder unqualifiziert auftreten soll. Dies ist insoweit wichtig, als dass z. B. XPathAusdrücke qualifizierte und unqualifizierte Elemente nicht automatisch finden, wenn sie nicht genau so angegeben werden, wie im Instanzdokument vorhanden. Daher muss man natürlich im Schema bereits die Verwendung angeben, damit aus der Schema-Datei herauszulesen ist, wie man auf die Elemente und Attribute zugreifen kann.
246
5. Auslagerung und Wiederverwendung
52_01da.xsd: Definition eines Schemas in einem bestimmten Namensraum
Jeder einzelne Berichtstyp besitzt ein passendes Schema-Dokument. In diesem Beispiel wird natürlich nur eines diskutiert. Über die Auslagerungstechnik gelingt es, ähnliche und gleiche Strukturen in externen Dateien zu lagern und in anderen Zusammenhängen zu verwenden. Da im vorherigen Dokument ein Namensraum angelegt wurde und dieser Namensraum in die aufrufende Schema-Datei übernommen werden soll, verwendet man erstens die Schema-Komponente import für die Übernahme der definierten globalen komplexen Typen und gibt zweitens im Attribut schemaLocation die Datei mit ihrem Verweispfad an, in der Namensraum und zu übernehmende Strukturen abgelegt wurden. Die aufrufende Schema-Datei übernimmt nun diesen Namensraum, der auch ihr eigener ist, und kann die Datentypen aus dem Namensraum da einsetzen. Wie schon zuvor müssen auch hier globale Inhalte wie komplexe und einfache Typen mit Namensraum-Präfix angegeben werden:
247
5
5. Auslagerung und Wiederverwendung
52_01.xsd: Verwendung importierter komplexer Typen
5
Abbildung 5.9: Verwendung importierter komplexer Typen
Man erhält im Ergebnis eine Schema-Datei mit Namensraumangabe, die Strukturen aus einem gleichen Namensraum bzw. aus einem anderen Dokument mit einem gleichen Namensraum übernimmt. Diese Strukturen in Form von globalen komplexen Typen und Datentypen lassen sich dann im Schema-Dokument wie die zuvor inkludierten Elemente aufrufen. Weil unterschiedliche Fälle denkbar sind und nicht für jeden Fall ein eigenes Beispiel verwendet werden soll, fassen diese beiden Bedingungen die jeweiligen Situationen zusammen, die jeweils zu einer gültigen Kombination aus Import-Dokument und importierenden Schema-Dokument führen: 1. Ist im import-Element ein namespace-Attribut mit einem Namensraum-URI vorhanden, kann dies ein anderer Namensraum als der im targetNamespace-Attribut des
248
5. Auslagerung und Wiederverwendung
schema-Elements des importierenden („umhüllenden“ gemäß Spezifikation) Doku-
ments sein. Es wäre also möglich, innerhalb des Namensraums der RuhrFon GmbH die Strukturen aus der ausgelagerten Datei des Dienstleisters zu verwenden, obwohl beide unterschiedliche Namensräume haben.
2. Ist im import-Element kein namespace-Attribut mit einem Namensraum-URI vorhanden, wird auch kein Namensraum aus dem aufgerufenen Dokument übernommen.
5. 2. 2. Übernahme ohne Namensraum Eine andere Syntax ergibt sich, sobald in der importierten Datei gar kein Namensraum verwendet wird. Abendessen p 2003 ... 52_02.xml: Ziel-Namensraum und Referenz eines XML Schemas
So kann man im folgenden Dokument zunächst die global deklarierten Elemente wie in den zurückliegenden Kapiteln auch immer ohne Namensraum-Präfix aufrufen.
249
5. Auslagerung und Wiederverwendung
...
52_02da.xsd: Keine Namensraumangabe
5
Beim Import verzichtet man wie zuvor auf die Verwendung des namespace-Attributs. Weil kein Zielnamensraum im importierten Dokument vorhanden ist, wird auch hier kein Namensraum übernommen. Die einzelnen Elemente aus der importierten Datei stehen außerhalb eines Namensraums für die Verwendung zur Verfügung.
250
5. Auslagerung und Wiederverwendung
52_02.xsd: Import ohne Namensraumangabe
5. 2. 3. Import mit eigener Namensraumangabe Eine dritte Situation ergibt sich, wenn verschiedene Namensräume zum Einsatz kommen. So besitzt die nachfolgende Datei einen eigenen Namensraum, auf dessen Präfix sich auch die verschiedenen anderen Schema-Komponenten beziehen, wenn es um die Verwendung von globalen Inhalten geht.
251
5
5. Auslagerung und Wiederverwendung
...
52_03da.xsd: Verwendung eines Zielnamensraumes
In einem solchen Fall benötigt die aufrufende Datei die jeweiligen Namensräume als Werte eines xmlns-Attribut, damit sie sich auf die verschiedenen globalen Inhalte beziehen kann. Dies ist natürlich nur der Fall, wenn tatsächlich auch ein Präfix verwendet werden soll. Dadurch erhält man im Ergebnis eine Schema-Datei, die sich auf diverse globale Inhalte bezieht, diese aber aus verschiedenen Namensräumen schöpft.
252
5. Auslagerung und Wiederverwendung
52_03.xsd: Import eines anderen Namensraumes
Für die XML-Datei bedeutet dies, dass sie nun den von der referenzierten XML SchemaDatei erwarteten RuhrFon-Namensraum angegeben muss. ...
52_03.xml: Verwendung eines Namensraumes
253
5
Gruppierungen und Ableitungskontrolle
6. Gruppierungen und Ableitungskontrolle
6. Gruppierungen und Ableitungskontrolle Erneut geht es in diesem Kapitel um Möglichkeiten der Auslagerung und Wiederverwendung. Allerdings treten dabei nicht Dateien in den Vordergrund, die über Import-, Inklusions- oder Redefinitionsregeln ihre Inhalte in eine andere Datei transportieren, sondern rein syntaktische Möglichkeiten der Inhaltsbeschreibung. Dazu zählen verschiedene Arten von Gruppen, von denen einige bereits bekannt sind, aber bisher noch nicht unter dem Blickwinkel der Wiederverwendung betrachtet wurden. Dazu zählen auch Überlegungen, wie Syntaxänderungen auf bestehende Strukturen Einfluss nehmen können. Dies ist ja gerade bei Anpassungen und Korrekturen ein wichtiger Aspekt. In Abhängigkeit von diesen unterschiedlichen Eigenschaften wie z. B. Verwendung von globalen komplexen Typen im Gegensatz zum Matrjoschka-Design, ergeben sich Einschränkungen oder Chancen für eine Wiederverwendung eines Schemas in anderen Zusammenhängen.
6. 1. Verwendung von Gruppen Grundprinzip der Wiederverwendung ist die Gestaltung von Gruppierungen, zu denen auf jeden Fall die Gruppen selbst, aber auch die globalen komplexen Typen zu zählen sind. Sie fallen zwar auch in den Bereich der Typenbildung, weil sie als strukturierte Typen angelegt und lokal über das type-Attribut aufgerufen werden, aber sie fassen dessen ungeachtet wie eine über group deklarierte Gruppe Kind-Elemente oder tiefer verschachtelte Strukturen zusammen. In beiden Fällen entsteht eine Sammlung von mindestens einem Element, das als Kind-Element eines anderen auftritt. Auf die globalen komplexen Typen wird im Zusammenhang mit den erweiterbaren Schemata nicht noch einmal eingegangen, da über sie in diesem Zusammenhang nichts Weiteres oder Neues gesagt werden kann als das, was schon bei ihrer Vorstellung zuvor zur Sprache kam. Ein zweites Grundprinzip ist die Auslagerung von Attributen und Elementen hin zu globalen Elementen und Attributen. Zu diesem Thema ist an dieser Stelle allerdings nichts Neues zu sagen, es wird aber noch einmal bei den erweiterbaren Schemata aufgegriffen.
255
6
6. Gruppierungen und Ableitungskontrolle
Abbildung 6.1: Grundprinzip Gruppierung bei der Auslagerung
Die Gruppen allerdings sollen noch einmal genauer untersucht werden, da bisher nur die Syntax für ihre Erstellung präsentiert wurde. Sie unterscheiden sich in drei Typen mit ähnlichen Eigenschaften:
6
●●
Elementgruppen: Innerhalb eines group-Containers wird global eine Gruppe deklariert, die sowohl aus Kind-Elementen wie auch aus tiefer verschachtelten Strukturen für ein anderes Element bestehen kann. Die Gruppe erhält einen Namen, der dann über das ref-Attribut in einem weiteren group-Element lokal aufgerufen wird, um die global vorhandenen Inhalte an diese Stelle zu übertragen.
Inhalt: (annotation?, (all | choice | sequence))
●●
Attributgruppen: Innerhalb eines attributeGroup-Containers wird global eine Gruppe von Attributen definiert. Diese lässt sich dann über ein weiteres attributeGroupElement mit Hilfe seines ref-Attributs lokal wieder aufrufen, um die global vorhandenen Inhalte an diese Stelle zu übertragen. Darüber hinaus können Attributgruppen auch verschachtelt werden. Es kann demnach eine Attributgruppe innerhalb einer anderen aufgerufen werden. Inhalt: (annotation?, ((attribute | attributeGroup)*,
●●
anyAttribute?))
Ersetzungsgruppen für Elemente: Ein benanntes Element, das entweder einen Textknoten (einfacher Inhalt), zusätzliche Attribute (komplexer Inhalt) oder Kind-Elemente (komplexer Typ) enthält oder alternativ auf einen entsprechenden globalen komplexen Typ verweist und von ihm die entsprechenden Inhalte übernimmt, kann als Ersetzung für ein anderes Element im Schema-Dokument auftreten. Dabei müssen sowohl die Ersetzung als auch das Element, das ersetzt werden soll, global definiert sein, wobei das zu ersetzende Element im Dokument lokal eine Referenz zum global deklarierten Element aufweist. An die Stelle des lokal deklarierten und mit dem globalen Element referenzierten Elements tritt dann die Ersetzung, wenn diese über das Attribut substitutionGroup und den Namen des global vorhandenen Elements mit diesem global vorhandenen Element in Verbindung steht.
6
Abbildung 6.2: Gruppen-Typologie
Neben den genannten Gruppen lassen sich auch noch Gruppierungen voneinander unterscheiden, die keinen eigenen Namen erhalten, aber dennoch innerhalb ihrer ContainerStruktur andere Elemente oder auch benannte Gruppen in einem group-Element enthalten. Dazu zählen die Zusammenstellung all, die Auswahl choice und die Reihenfolge se-
257
6. Gruppierungen und Ableitungskontrolle
quence. Sie sind für die Auslagerung selbst nicht interessant, da sie wegen der fehlenden
Bezeichnungsmöglichkeit nicht an anderer Stelle aufgerufen werden können. Von daher spielen sie nur bei der Angabe von Inhaltsmodellen als Container-Elemente eine Rolle.
6. 1. 1. Element- und Attributgruppen Zunächst sollen die bereits bekannten Konzepte der Element- und Attributgruppen noch einmal an einem einfachen Beispiel erläutert werden, um sie nachher mit dem Konzept der Element-Ersetzungsgruppe zu vergleichen. Das Instanzdokument, das hier validiert werden soll, enthält eine Umsatzübersicht mit sowohl Geschäfts- als auch Privatkunden. Während für die Geschäftskunden die Elemente Name und Branche für die Identifikation neben der Kundennummer im Attribut Nr verwendet werden, existieren für die Privatkunden die beiden Elemente Vorname und Nachname.
6
Dies ließe sich als unregelmäßige oder flexible Datenstruktur beschreiben. Unregelmäßig ist sie insoweit, als dass entweder die eine Gruppe von Elementen erscheint oder die andere. Das hängt von einem bestimmten Wert in einem Attribut Typ ab, das die beiden Inhalte p oder g annehmen kann. Dadurch ist diese Unregelmäßigkeit durchaus reglementiert und für den tatsächlichen Sachverhalt eindeutig, aber bei der Modellierung schwierig umzusetzen. Flexibel ist dieses Inhaltsmodell dadurch, dass unterschiedliche Inhalte in einem Eltern-Element auftreten können. Muck Industrietechnik GmbH Automatenbau 494.83 Kieferstr. 12 44225 Dortmund 231 9483
258
6. Gruppierungen und Ableitungskontrolle
Dressler
F.
22.12
Girardetstr. 46 45131 Essen. Ruhr
201
310923
61_01.xml: Unregelmäßige Datenstruktur
6
6. 1. 1. 1 Gruppen für Elemente Bei der Einführung der Syntax, mit der die Elementgruppen deklariert werden, wurde zunächst gezeigt, dass eine solche Struktur auch sehr einfach über optionale Elemente eingerichtet werden kann. Hierbei tauchte das Problem auf, dass dann durch die Optionalität jedes Elements sowohl das vollkommene Fehlen aller als auch eine ungewollte Kombination aus Elementen für den Geschäfts- und Privatkunden gültige Instanzdokumente hervorbringt. Dies ist selbstverständlich weder im Sinne der Anwendung noch syntaktisch unausweichlich. Über eine Auswahl lässt sich bereits lokal eine Reihenfolge für jede Datenstruktur einrichten, die jeweils die korrekte Kardinalität, Existenz und natürlich Reihenfolge vorgibt. Im Zusammenhang mit der Auslagerung von Datenstrukturen ergibt sich dann ein Vorteil, wenn die beiden möglichen Gruppen global angegeben und dann lokal in einer Auswahl aufgerufen werden, da in einem solchen Fall die jeweiligen Datenstrukturen global und nicht lokal vorliegen. Dieses Vorgehen zeigt die folgende Schema-Datei mit den beiden Gruppen PKunde und GKunde, die jeweils später im Dokument referenziert werden.
259
6. Gruppierungen und Ableitungskontrolle
6 ...
61_01.xsd: Gruppen für Elemente
Abbildung 6.3: Modellierung mit Elementgruppen
260
6. Gruppierungen und Ableitungskontrolle
In Abbildung 6.3 erkennt man deutlich, dass die direkten Kind-Elemente der Auswahl die beiden Gruppen mit den Datenstrukturen für den Privat- und Geschäftskunden sind. Sie werden aus den global vorhandenen Gruppen an dieser Stelle eingefügt und stellen dort ihre Inhalte bereit.
6. 1. 1. 2 Gruppen für Attribute Für Attribute lässt sich ein ähnlicher Mechanismus nutzen. In diesem Fall setzt man so genannte „Attributgruppen“ ein, die für mehrfach zusammen auftretende Attribute überaus nützlich sind. In diesem Fall handelt es sich um die beiden Attribute Nr und Typ, die jeden Kunden mit seinem Schlüsselwert und seiner Kategorie charakterisieren. Wie zuvor schon bei den Elementgruppen dient auch hier dieselbe Schema-Komponente für die Referenzierung und die Deklaration der Inhalte. Außen bzw. global liegt die Attributgruppe als direktes Kind-Element von schema und ist lokal referenzierbar über seinen Namen. Diesen definiert man außen mit dem name-Attribut, um sich innen auf ihn mit dem ref-Attribut zu beziehen. ...
6
261
6. Gruppierungen und Ableitungskontrolle
61_02.xsd: Gruppen für Attribute
6. 1. 2. Ersetzungsgruppen für flexible Inhalte
6
Als Alternative zu den gerade vorgestellten Gruppen lassen sich noch die Element-Ersetzungsgruppen verwenden. Sie ähneln den anderen Gruppen insoweit, als dass auch hier eine Gruppierung für die Kombination von Elementen verwendet wird. Sie unterscheidet sich allerdings doch sehr von den vorgestellten Elementgruppen durch den Umstand, dass es hier keinen Container und auch keinen Namen gibt, über den diese Gruppen angesprochen werden können. Vielmehr handelt es sich um einen Ersetzungsmechanismus, der zwischen global deklarierten Elementen über ihren eigenen, im name-Attribut angegeben Namen abläuft und über das substitutionGroup-Attribut anstelle des ref-Attributs für Gruppen eingerichtet wird.
6. 1. 2. 1 Verwendung bei Elementen Wie schon an anderer Stelle erläutert, bietet sich bei ähnlichen, aber nicht gleichen Datenstrukturen in einem Dokument die Möglichkeit an, dies entweder über Schaltattribute mit standardisierten Werten in Form von Kategorien zu behandeln oder verschiedene Eltern-Elemente einzusetzen. Im folgenden Dokument ist neben dem Schaltattribut für das Element Kunde auch noch ein zusätzliches Eltern-Element eingefügt, um die Namensbestandteile des jeweiligen Kunden extra herauszuheben. Dies hat in dieser Kombination den Vorteil, dass man weiterhin über einen sehr einfachen XPath-Ausdruck in der Form //Kunde alle Kunden, und über //Kunde[@Typ=‘g‘] alle Geschäftskunden genauso wie zuvor findet. Alternativ kann man nun aber auch über den sehr einfachen Ausdruck //Kunde/ GKunde/* oder //Kunde/PKunde/* alle Namensbestandteile eines einzelnen Kundentyps finden. Alle Namensbestandteile von allen Kunden findet man dann über den – zugegebenermaßen – nicht mehr ganz so einfachen Ausdruck //Kunde/*[name()=‘GKunde‘ or name()=‘PKunde‘]. Das Kriterium der Schlichtheit für die einfache Adressierung ist
262
6. Gruppierungen und Ableitungskontrolle
allerdings weitestgehend erfüllt, sodass eine solche Datei auch im Zusammenhang mit der Transformation einfach zu verwenden ist.
Muck Industrietechnik GmbH
Automatenbau 494.83
...
Dressler F. 22.12
6
...
61_03.xml: Verwendung unterschiedlicher Elemente
Die Überlegungen bezüglich der Modellierung für eine Verwendung von Elementstrukturen im Instanzdokument ist im Zusammenhang mit der Syntax der Element-Ersetzungsgruppen gar nicht so entscheidend wie die Gestaltung des Schema-Dokuments selbst. Mit der Technik der Element-Ersetzungsgruppe bietet nämlich die XML Schema-Syntax eine Technik für die Gestaltung der Schema-Datei und weniger für die Modellierung selbst. In diesem Sinne lässt sie sich leicht mit den Ableitungsmöglichkeiten vergleichen, die ebenfalls für das Modellierungsergebnis in Form von Element- und Attributnamen sowie ihren Datentypen und ihren Hierarchie- sowie Kardinalitätsbeziehungen weniger bedeutend sind als für den Modellierungsvorgang, bei dem über die Verwendung von Ableitungen aus Grundstrukturen lokal individualisierte bzw. angepasste Strukturen erzeugt werden. Das Grundprinzip der Element-Ersetzungsgruppe besteht darin, zwischen global deklarierten Elementen, die lokal über eine Referenz im ref-Attribut aufgerufen werden, eine Er-
263
6. Gruppierungen und Ableitungskontrolle
setzung eines Elements im Dokument durch die anderen Elemente stattfinden zu lassen. Dabei referenziert man lokal ein so genanntes „abstraktes Element“, das über seinen Namen im Attribut substitutionGroup in den anderen globalen Elementen, die an seine Stelle treten sollen, ebenfalls referenziert wird. Dadurch treten – je nach Einstellung – die Ersetzungen an die Stelle des lokal referenzierten abstrakten Elements. Man erhält im Instanzdokument – ebenfalls je nach Einstellung – also gerade nicht das erwähnte abstrakte Element, sondern seine Ersetzungen. An diesem erläuterten Grundprinzip erkennt man bereits, dass tatsächlich weniger das Modellierungsergebnis im Vordergrund steht, sondern vielmehr die Vorgehensweise bei der Modellierung selbst.
6
Mag die Syntax und das Vorgehen vielleicht auf den ersten Blick umständlich wirken, so gewinnt man innerhalb der verschachtelten Strukturen die Möglichkeit, ähnliche, aber nicht gleiche Strukturen durch einen gemeinsamen Namen zu belegen und ihre genauen Inhalte global vorzugeben. Der Vorteil, Strukturen mehrfach zu verwenden oder global zu pflegen, wie er schon durch Elemente, Gruppen oder komplexe Typen erreicht wird, ergänzt sich hier durch die Element-Ersetzungsgruppen um die Möglichkeit, innerhalb der lokalen Deklarationen Vereinfachungen in der Syntax vorzunehmen. Diese liegen gerade nicht nur darin, außen liegende Inhalte aufzurufen und lokal verfügbar zu machen. Es werden vielmehr ähnliche, aber nicht gleiche Strukturen unter einem gemeinsamen Namen verwaltet. Dies lässt sich im aktuellen Beispiel immer an der Unterscheidung der verschiedenen Kundenarten sehen, was sich in jedem Dokument fortsetzt, in dem diese unterschiedlichen Typen auftreten. Es handelt sich um eine ähnliche Datenstruktur, da der Name des Kunden und eine zusätzliche Angabe in Form der Branche bei Geschäftskunden erfasst werden. Letztendlich handelt es sich allerdings immer um weniger genaue bzw. identifizierende Bezeichnungen als der Primärschlüssel, der im Nr-Attribut des Kunde-Elements untergebracht wird, sodass lokal auf eine explizite Unterscheidung oder Angabe der jeweiligen Kind-Elemente verzichtet werden kann und man stattdessen auf Gruppen, globale komplexe Typen oder die Element-Ersetzungsgruppen zurückgreift. Im letzten Fall kann man dann sogar das gleiche Element wählen. Konkret erhält man im Beispiel ein Element Name, das als abstraktes Element mit dem Attribut abstract und dem Wert true ausgezeichnet wird. Durch diese Angabe unterbindet man die Verwendung von Name im Instanzdokument. Bei false hingegen wäre dies durchaus möglich, d. h., die Ersetzung wäre nur eine mögliche gültige Form des Instanzdokuments. Des Weiteren existieren global zwei Elemente mit Kind-Elementen für die jeweiligen Datenstrukturen der Kunde-Elemente. Dies sind die beiden globalen Elemente PKunde und GKunde, die jeweils in einem speziellen Attribut substitutionGroup den Namen des Elements aufrufen, das sie ersetzen sollen. In diesem Fall handelt es sich natürlich um das globale Element Name. Dieses wiederum befindet sich mit einer einfachen
264
6. Gruppierungen und Ableitungskontrolle
lokalen Referenz auf das globale Element Name an der Stelle, wo die Kundendatenstruktur für den Namen in Form der individuellen Datenstruktur für Privat- und Geschäftskunden zu finden sein soll. Hier ist nun der entscheidende Unterschied zu den anderen Techniken zu erkennen. Statt einer Auswahl befindet sich nur die Referenz auf das abstrakte Element an dieser Stelle, das durch seine jeweiligen Ersetzungen ausgetauscht wird. Es können alternativ (quasi eine automatische oder implizite Auswahl) PKunde oder GKunde mit jeweils unterschiedlichen Kind-Elementen sein.
6
...
61_03.xsd: Verwendung einer Ersetzungsgruppe für gleiches Element in Schema-Datei und unterschiedliches Element in Instanz
265
6. Gruppierungen und Ableitungskontrolle
Abbildung 6.4 zeigt schematisch die Ersetzung des Elements Name durch die beiden anderen möglichen Elemente PKunde und GKunde mit ihren jeweiligen Inhalten. Gültig ist ein Instanzdokument nur dann, wenn eines von beiden Elementen an der Stelle von Name im Dokument auftritt. Name selbst darf nicht zum Einsatz kommen.
6
Abbildung 6.4: Ersetzungsgruppen bei Elementen
Die schematische Darstellung mit Quelltext zeigt die unterschiedlichen Bezüge in der Datei. Auf der einen Seite gibt es das abstrakte Element, auf das sich sowohl die lokale Referenz mit dem ref-Attribut als auch die beiden Ersetzungen mit dem substitutionGroupElement beziehen. Auf der anderen Seite wird dadurch indirekt eine Beziehung hergestellt zwischen der lokalen Referenz, deren Existenz über den Ort des Ersetzungsvorgangs entscheidet (also genau vor dem noch in der Grafik gezeigten Umsatz-Element), und den beiden Ersetzungen. Deutlich wird auch, wie knapp der Quelltext lokal wird, da man nur noch eine einzige Zeile benötigt, um die passende Datenstruktur zu übernehmen.
266
6. Gruppierungen und Ableitungskontrolle
6
Abbildung 6.5: Prinzip der Element-Ersetzungsgruppen
6. 1. 2. 2 Kopf-Element und abstraktes Element Für eine korrekte Funktionsweise der Ersetzungsgruppen ist nicht nur die richtige Syntax im Hinblick auf die unterschiedlichen Referenzen und die Existenz des abstrakten Elements sowie der möglichen Ersetzungen als globale Elemente von Bedeutung, sondern auch die Wahl der Datentypen. Offensichtlich handelt es sich um eine Ersetzung, technisch handelt es sich aber um eine Ableitung, d. h., die jeweiligen Ersetzungen müssten vom abstrakten Element abgeleitet werden können. Dies ist vor allen Dingen dann der Fall, wenn die Datentypen für solche Abteilungen geeignet sind. Im einfachsten Fall geht es nicht um ein abstraktes Element, sondern um ein so genanntes „Kopf-Element“. Abstrakt wird es erst durch die Angabe bzw. Verwendung von abstract. Ist der Wert true, darf das Element selbst im Instanzdokument nicht verwendet werden. Ist der Wert false, darf es auch anstelle der Ersetzungen (Ersetzung der Ersetzung) mit dem angegebenen Datentyp (siehe später) im Instanzdokument verwendet werden. Ge-
267
6. Gruppierungen und Ableitungskontrolle
meinhin ist es stets als Kopf-Element der gesamten Ersetzungsgruppe zu bezeichnen. Diese besteht also aus dem Kopf-Element, das ein abstraktes Element sein kann, und den jeweiligen Ersetzungen. Im aktuellen Beispiel ist demnach das Element Name ein Kopf-Element, das gleichzeitig auch abstrakt ist und mit den beiden Ersetzungen PKunde und GKunde eine Ersetzungsgruppe bildet. Sie hat keinen eigenen Namen, sondern wird indirekt durch den in den name- und substitutionGroup-Attributen verwendeten Namen benannt.
6 Abbildung 6.6: Ersetzungsgruppenstruktur
Da eine Datentyp-Angabe fehlt, handelt es sich standardmäßig um den Datentyp xs:anyType. Er bezeichnet alle möglichen Datentypen und ist für abstrakte Elemente bzw. Kopf-Elemente oft der richtige, weil dann die Ableitung in jedem Fall korrekt verläuft. Wichtig ist also, dass die Datentypen der Mitglieder der Element-Ersetzungsgruppe ableitbar sind vom Datentyp des Kopf-Elements, was natürlich bei xs:anyType stets gegeben ist. Möchte man die Verwendung des Kopf-Elements im Instanzdokument erlauben, muss es nicht nur als abstraktes Element mit dem Wert false ausgezeichnet werden, sondern auch einen passenden Datentyp erhalten, damit nur geeignete Werte im Instanzdokument erscheinen. Im aktuellen Beispiel könnten dies natürlich Firmennamen bzw. Zeichenketten sein. Damit handelt man sich aber auch die Schwierigkeit ein, dass die davon abzuleitenden Datentypen der Mitglieder der Ersetzungsgruppe tatsächlich vom Datentyp des abstrakten Elements ableitbar sind.
268
6. Gruppierungen und Ableitungskontrolle
6. 1. 2. 3 Verwendung bei globalen komplexen Typen Eine weitere Vereinfachung bzw. Auslagerung ergibt sich, wenn man die Verwendung von globalen komplexen Typen mit dem Ersetzungsgruppenmechanismus kombiniert. Dies soll folgendes Beispiel verdeutlichen, bei dem jeweils ein eigener globaler komplexer Typ für die Datenstruktur von Geschäfts- und Privatkunde existiert. Ein gemeinsamer Typ mit einer Auswahl wäre im Übrigen nicht denkbar, weil in Abhängigkeit vom Eltern-Element ja gerade unterschiedliche Kind-Elemente zu verwenden sind. Bei einer Auswahl innerhalb des globalen komplexen Typs, der für beide Datenstrukturen im type-Attribut aufgerufen wird, könnte man zwar die beiden zusammengehörigen Elemente jeweils voneinander trennen, jedoch ihre Verwendung nicht in Abhängigkeit vom Eltern-Element steuern.
6
269
6. Gruppierungen und Ableitungskontrolle
...
61_04.xsd: Ersetzungsgruppen bei globalen komplexen Typen
Abbildung 6.7 visualisiert die Verwendung von globalen komplexen Typen für die beiden Mitglieder der Ersetzungsgruppe anhand der üblichen Darstellung für den Aufruf von globalen komplexen Typen. Prinzipiell unterscheidet sich hier also nichts von der sonst auch üblichen Syntax mit Ausnahme des Attributs substitutionGroup in beiden Elementen.
6
Abbildung 6.7: Einsatz von globalen komplexen Typen bei Mitgliedern einer Ersetzungsgruppe
Der in Abbildung 6.8 gezeigte Quelltext veranschaulicht noch einmal die diversen Referenzen zwischen globalen komplexen Typen, globalen Elementen und lokalen Elementen. Die beiden globalen komplexen Typen werden in den Mitgliedern der Element-Ersetzungsgruppe im type-Attribut aufgerufen und stellen dort die jeweiligen Kind-Elemente individuell für jeden Kundentyp zur Verfügung. Über das substitutionGroup-Attribut in beiden Mitgliedern stehen diese mit dem Kopf-Element ohne type-Angabe in Beziehung. Über die Ersetzung, die zum einen durch die Einrichtung der Ersetzungsgruppe zwischen den globalen Elementen und zum anderen über die Referenzierung des Kopf-Elementes lokal bestimmt wird, überträgt man die jeweiligen Kind-Elemente in einer impliziten Auswahl
270
6. Gruppierungen und Ableitungskontrolle
an die gewünschte Stelle. Interessant an dieser Konstruktion ist der Einsatz eines globalen komplexen Typs für jede Datenstruktur.
6
Abbildung 6.8: Verwendung von globalen komplexen Typen
Es lässt sich im Vergleich zum vorherigen Beispiel ein weiterer Fall konstruieren, der mit dem vorherigen den Einsatz eines globalen komplexen Typs gemein hat, sich aber vom vorherigen Beispiel grundsätzlich unterscheidet. Dabei liegt der Unterschied im Aufruf des globalen komplexen Typs. Bisher hatte das Kopf-Element keinen ausgewiesenen Datentyp bzw. explizit den Datentyp xs:anyType, von dem die anderen Elemente abgeleitet werden konnten. Es besteht jedoch auch die Möglichkeit, die gesamte Datenstruktur in Form der beiden Kind-Elemente innerhalb einer Auswahl festzulegen. Achtung: Hier entfällt jetzt die Überprüfung, ob die beiden Kind-Elemente für GKunde und PKunde die gewünschten sind. Daher ist dieses Beispiel nur aus syntaktischen Gründen interessant, aber in jedem Fall liegt eine schlechtere Modellierung vor als bei den vorhergehenden Beispielen.
271
6. Gruppierungen und Ableitungskontrolle
Der gerade beschriebene (und kritisierte) globale komplexe Typ wird nun nicht in den beiden Mitgliedern aufgerufen, sondern stattdessen im Kopf-Element. Weil beide Mitglieder jeweils keinen Datentyp erhalten, übernehmen sie später die Datentypzuweisung vom Kopf-Element. Dies entspricht prinzipiell dem Standardfall, wenngleich auch hier jedes Mal der Datentyp durch Ableitung von xs:anyType geändert wurde. Der Aufruf und die Einrichtung der Ersetzungsgruppe mit Hilfe von substitutionGroup bleibt weiterhin erhalten. Lokal im Dokument ruft man nun in einer Auswahl die beiden Alternativen auf, die für die Abbildung einer Kundendatenstruktur möglich sind. Dadurch wird entweder das Element GKunde oder das Element PKunde mit dem Inhalt aus dem übernommenen globalen komplexen Typen KundeTyp im Instanzdokument validiert. Dies allerdings mit der Einschränkung, dass auch nicht-passende Kind-Elemente zugelassen sind. Syntaktisch korrekt und interessant ist es dennoch.
6
272
6. Gruppierungen und Ableitungskontrolle
...
61_05.xsd: Verwendung eines globalen komplexen Typs im abstrakten Element
In der schematischen Darstellung der Elementstruktur erkennt man nicht, dass es sich um eine Ersetzungsgruppe handelt.
6
Abbildung 6.9: Verwendung eines globalen komplexen Typs im abstrakten Element
In der Struktur-Ansicht mit Quelltext in Abbildung 6.10 ist deutlich zu sehen, wie der globale komplexe Typ im Kopf-Element der Ersetzungsgruppe aufgerufen wird, und dass sich die beiden Mitglieder der Gruppe weiterhin im Attribut substitutionGroup auf das KopfElement beziehen. Lokal allerdings referenziert man in einer Auswahl die beiden Mitglieder und gerade nicht das Kopf-Element, was dazu führt, dass man in die beiden Mitglieder die Kind-Elemente des Kopf-Elements kopiert bzw. über den Ersetzungsgruppenmechanismus die Typangabe aus dem globalen komplexen Typ für beide Elemente bereit stellt.
273
6. Gruppierungen und Ableitungskontrolle
6 Abbildung 6.10: Globaler komplexer Typ im abstrakten Element
6. 1. 2. 4 Verwendung bei Attributen Die einzelnen Elemente in einer Element-Ersetzungsgruppe können natürlich Attribute besitzen wie jedes andere Element auch. Es ist allerdings nicht möglich, einen ähnlichen Mechanismus auch für Attributgruppen zu verwenden. Hier sind keine Ersetzungen von einem lokalen Attribut durch Attributstrukturen, die global als Attribut-Ersetzungsgruppe festgelegt sind, möglich. Das gesamte Vorgehen bleibt ausschließlich den Elementen vorbehalten.
274
6. Gruppierungen und Ableitungskontrolle
6. 2. Ableitungen kontrollieren Elemente, einfache Typen und komplexe Typen lassen sich, wie nun an unterschiedlichen Stellen dargestellt, entweder global im gleichen Dokument gestalten oder sogar in einem externen Dokument festlegen, wobei sie dann durch Inklusion, Redefinition oder Import in anderen Dokumenten als globale Elemente bereit stehen. Bei der Redefinition und der Verwendung von globalen Schema-Komponenten im gleichen Dokument gibt es die Möglichkeit der Ableitung durch Einschränkung, durch Erweiterung und – wie soeben beschrieben – auch der Ersetzung für komplexe Typen und Elemente. Für einfache Typen gibt es die Ableitung durch Erweiterung, Auflistung und Vereinigung.
6. 2. 1. Grundproblem und Lösung Mit der Möglichkeit, Ableitungen vorzunehmen, entstehen Hierarchien innerhalb der Definitionsstrukturen, die genauso erwünscht wie unerwünscht sein können. Erwünscht sind solche Abhängigkeiten insbesondere dann, wenn sie kontrolliert und geplant werden, was dem bisher behandelten Fall von Auslagerung, Wiederverwendung und Ableitung entspricht. Werden Änderungen an den allgemeinen Strukturen wie z. B. an den Datentypen vorgenommen, sollen sich diese Änderungen gerade überall dort fortpflanzen, wo die entsprechenden Strukturen verwendet werden. Dass dabei auch schon einmal Änderungen der Art vorgenommen werden, die nicht zu den darauf aufbauenden bzw. sie verwendenden Strukturen passen bzw. Fehler auslösen, ist ein kalkulierbares Risiko. Der Schema-Autor nämlich bemerkt entsprechende Fehler unmittelbar oder wenig später und erinnert sich dann möglicherweise daran, welche Änderungen zu einem entsprechenden Fehler führten. Typischerweise dürfte sich in einem entsprechenden Editor auch das fehlerhaft verwendete Dokument öffnen und genau die Stelle lokalisieren, an der falsch auf eine dort stehende Ressource verwiesen wird. Das zuvor beschriebene Szenario setzt allerdings voraus, dass der Schema-Autor der Änderung auch derjenige der späteren Benutzung ist bzw. dass die gesamte Anwendung quasi immer auf der gleichen Tastatur entwickelt wurde. Sobald aber umfangreiche Datenstrukturen wie Kataloge, zugehörige Formblätter zur Texterfassung, Produktblätter, Änderungsinformationen und dergleichen zu erstellen sind, die ihre Daten weitestgehend alle aus der gleichen Datenbasis besorgen und von mehreren Mitarbeitern gepflegt und entwickelt werden, entstehen natürlich Situationen, in denen gerade nicht jedem Team-Mitglied bekannt ist, welche Änderungen aktuell sind. Auch eine Dokumentation und Änderungshistorie kann hier versagen, weil nicht garantiert werden kann, dass sie auch kontinuierlich eingesehen wird. Zudem kann es vorkommen, dass ein Schema-Autor, der mit Änderungen
275
6
6. Gruppierungen und Ableitungskontrolle
beschäftigt ist, Informationen aus der vorletzten Woche nicht damit in Beziehung bringt, so dass die in den Änderungen referenzierten Strukturen eventuell ungültig sind.
Externe Datei mit allgemeinen Datenstrukturen Globaler komplexer Typ Globales Element Globaler einfacher Typ
Modellierung von Datenstrukturen Verwendung allgemeiner Datenstrukturen
Funktionsweise von Auslagerung und Wiederverwendung
Bereitstellung Aufruf externe Datei Eigentliche Modellierung unter Verwendung der eingebundenen Strukturen
Änderung an allgemeinen Datenstrukturen Globaler komplexer Typ Globales Element Globaler einfacher Typ
6 Gefahr durch Änderung bei Abhängigkeiten
Aktualisierte Bereitstellung
Fehler
Aufruf externe Datei Eigentliche Modellierung unter Verwendung der eingebundenen Strukturen
Abbildung 6.11: Abhängigkeiten zwischen Dokumenten und Strukturen
Kurz und gut: Die Änderungen an allgemeinen Strukturen, die später in andere Dokumente eingebunden werden, können für bereits bestehende Ableitungen und Verweise so ungünstig sich auswirken, dass die bereits bestehenden Abhängigkeiten fehlerhaft werden. Die Änderungen an speziellen Strukturen können sich auf ehemalige allgemeine Strukturen beziehen, die in der Zwischenzeit allerdings Änderungen unterworfen wurden, die derzeit nicht bekannt sind. Auch in zusätzlich denkbaren Kombinationsfällen läuft das Problem der fehlerhaften Abhängigkeit von speziellen zu allgemeinen oder von allgemeinen zu speziellen Strukturen darauf hinaus, dass ein Teil der fehlerhaften Abhängigkeiten hätte vermie-
276
6. Gruppierungen und Ableitungskontrolle
den werden können, wenn die Abhängigkeiten erst gar nicht eingerichtet worden wären. Diese Abhängigkeiten liegen nun sowohl in den bekannten und sehr einfachen Aufrufen über das type- oder ref-Attribut, sondern insbesondere – was für diesen Abschnitt von Bedeutung ist – in den Ableitungen von globalen Strukturen. Abbildung 6.11 soll dieses Grundproblem anhand zweier Dokumente veranschaulichen. Zum einen enthält das Beispiel das Prinzip der Auslagerung und Wiederverwendung, wobei Einbindungsvorgänge die entsprechenden Strukturen des einen Dokuments in ein anderes Dokument einbringen. Es wäre auch ein einziges Dokument denkbar, in dem die Strukturen direkt als globale Inhalte bereit stehen. Solange keine falschen oder auf falsche Annahmen über die Inhalte beruhenden Ableitungen (der einfache Aufruf muss hier unberücksichtigt bleiben) der Strukturen stattfinden, bieten solche Ableitungen natürlich ausschließlich die Vorteile, wie sie bereits zuvor dargestellt wurden. Arbeiten allerdings mehrere Team-Mitglieder an einem Modellierungsprojekt oder greifen sie jeweils auf gemeinsame Dateien zu, dann können sich über die Ableitungstechnik Gefahren und Nachteile für die Qualität von Modellierungen einschleichen. Dies ist bei dem kurzen Beispiel in diesem Buch relativ theoretisch und wird nicht vorkommen, weil meistens nur auf eine einzige Datei zugegriffen wird, die nicht einen geraden überlangen Quelltext enthält. Möchte man allerdings die Ableitungsmöglichkeiten von vorneherein ausschließen und damit indirekt nur eine Verwendung, nicht aber eine Veränderung zulassen, bieten sich verschiedene zusätzliche Attribute an, mit denen Ableitungen kontrolliert werden können.
6. 2. 2. Vorgabemöglichkeiten Für die drei Schema-Komponenten globale Elemente, globale komplexe Typen und einfache Typen sollen in der folgenden Übersicht die verschiedenen Einstellungen für die beiden zusätzlichen Attribute block und final dargestellt werden. Ihre Werte ergeben sich aus den jeweilig zulässigen Ableitungstechniken für die entsprechende Schema-Komponente. Mit dem Attribut final beschränkt man durch Angabe der Ableitungstechnik die Ableitungsmöglichkeiten. Mit dem Attribut block beschränkt man die Substituierbarkeit, also die Verwendung der so gesperrten Schema-Komponenten für ein Kopf-Element einer Element-Ersetzungsgruppe. Die jeweiligen Werte für beide Attribute werden in einer XMLListe in einer durch Leerzeichen getrennten Aufzählung von Werten angegeben.
277
6
6. Gruppierungen und Ableitungskontrolle
Die folgende Übersicht zeigt nicht nur die verschiedenen Kontrollmöglichkeiten der Schema-Komponenten, sondern auch welche Ableitungen überhaupt für die jeweilige SchemaKomponente möglich sind. ●●
Elemente lassen sich sowohl ableiten als auch als Kopf-Element für eine Element-Ersetzungsgruppe verwenden. Demzufolge besitzen sie beide Attribute, um die jeweilige Wiederverwendung zu beschränken. Die Werte für beide Attribute entsprechen den jeweiligen Verfahren. Mit #all unterbindet man alle Techniken. block: Dieses Attribut verhindert, dass ein Element diesen Typs von einem Element
ersetzt wird, das durch die angegebene Ableitungstechnik erzeugt wird. Mögliche Werte sind extension, restriction, #all oder substitution.
extension: Verhindert den Einsatz eines durch Erweiterung abgeleiteten Elements anstelle des angegebenen. restriction: Verhindert den Einsatz eines durch Einschränkung abgeleiteten Elements anstelle des angegebenen. substitution: Verhindert den Einsatz eines durch Ersetzung erzeugten Elements anstelle des angegebenen.
6
#all: Verhindert den Einsatz eines durch Erweiterung, Einschränkung und durch Ersetzung abgeleiteten Elements anstelle des angegebenen. final: Dieses Attribut verhindert, dass ein Element diesen Typs von einem Element er-
setzt wird, das durch die angegebene Ableitungstechnik erzeugt wird. Mögliche Werte sind extension, restriction, oder #all.
extension: Verhindert den Einsatz eines durch Erweiterung abgeleiteten Elements anstelle des angegebenen. restriction: Verhindert den Einsatz eines durch Einschränkung abgeleiteten Elements anstelle des angegebenen. #all: Verhindert den Einsatz eines durch Erweiterung und Einschränkung abgeleiteten Elements anstelle des angegebenen.
278
6. Gruppierungen und Ableitungskontrolle
Diese Einstellungen gelten nur für globale Elemente und nicht für lokale, die ja auch gar nicht abgeleitet werden können. Inhalt: (annotation?, ((simpleType | complexType)?,
●●
(unique | key | keyref)*))
Komplexe Typen lassen sich sowohl ableiten als auch als Typen für eine Element-Ersetzungsgruppe verwenden. Demzufolge besitzen sie beide Attribute, um die jeweilige Wiederverwendung zu beschränken. Die Werte für beide Attribute entsprechen den jeweiligen Verfahren. Mit #all unterbindet man alle Techniken. block: Dieses Attribut verhindert, dass ein globaler komplexer Typ, der durch die an-
gegebene Ableitungstechnik erzeugt wird, anstelle des angegebenen globalen komplexen Typs verwendet wird. Mögliche Werte sind extension, restriction oder #all. Dieses Attribut kommt nur zum Einsatz, wenn im Instanzdokument der erwartete Typ durch die Verwendung von xsi:type überschrieben wird. Damit kann unter keinen Umständen anstelle eines komplexen Typs ein anderer, der durch Ableitung erzeugt wurde, verwendet werden. extension: Verhindert den Einsatz eines durch Erweiterung abgeleiteten komplexen Typs anstelle des angegebenen. restriction: Verhindert den Einsatz eines durch Erweiterung abgeleiteten komplexen Typs anstelle des angegebenen. #all: Verhindert den Einsatz eines durch Erweiterung und Einschränkung abgeleiteten komplexen Typs anstelle des angegebenen. final: Dieses Attribut verhindert, dass ein globaler komplexer Typ, der durch die angegebene Ableitungstechnik erzeugt wird, verwendet wird. Mögliche Werte sind exten-
279
6
6. Gruppierungen und Ableitungskontrolle
sion, restriction oder #all. Damit kann unter keinen Umständen ein komplexer
Typ abgeleitet werden.
extension: Verhindert die Ableitung durch Erweiterung. restriction: Verhindert die Ableitung durch Einschränkung. #all: Verhindert die Ableitung durch Erweiterung und durch Einschränkung. Diese Einstellungen gelten nur für globale komplexe Typen und nicht für lokale, die ja auch gar nicht abgeleitet werden können. Inhalt: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
6 ●●
Einfache Typen lassen sich ableiten durch drei verschiedene Techniken. Mit final unterbindet man alle Techniken mit Hilfe der Werte list, union, restriction und #all. final: Dieses Attribut verhindert, dass ein globaler einfacher Typ, der durch die angegebene Ableitungstechnik erzeugt wird, verwendet wird. Mögliche Werte sind list, union, restriction und #all. Damit kann unter keinen Umständen ein einfacher
Typ abgeleitet werden.
list: Verhindert die Ableitung durch Auflistung (nur einfache Typen). union: Verhindert die Ableitung durch Vereinigung (nur einfache Typen). restriction: Verhindert die Ableitung durch Einschränkung.
280
6. Gruppierungen und Ableitungskontrolle
extension: Verhindert die Ableitung durch Erweiterung (nur Elemente und komplexe Typen). #all: Verhindert die Ableitung durch alle drei Formen. Diese Einstellungen gelten nur für globale einfachen Typen und nicht für lokale, die ja auch gar nicht abgeleitet werden können.
Inhalt: (annotation?, (restriction | list | union))
●●
Schema-Standardeinstellung: Für das schema-Element lassen sich allgemeine Standardeinstellungen vorgeben, die sich auf globale Schema-Komponenten der entsprechenden Datei auswirken und dann lokal durch Werte für block und final überschreiben lassen.
...
91_01.xsd: Einsatz von XML-Kommentaren
Diese XML-Kommentare haben den Vorteil, dass man sie sehr leicht verwenden kann und sie an nahezu beliebiger Stelle stehen können. Sie haben allerdings den Nachteil, dass man sie mit XSLT nicht derart auslesen kann, dass man wüsste, welche XML Schema-Strukturen sie kommentieren, denn XML-Kommentare sind ja keine Kind-Elemente von XML-Elementen, sondern stehen außerhalb der XML-Struktur – egal, wo sie in der Datei untergeordnet sind.
9
362
9. Dokumentation
9. 1. 2. XML Schema-Kommentar-Elemente XML Schema hat darüber hinaus eigene Kommentar-Elemente, die Container-Elemente1 mit unterschiedlichen Kind-Elementen sind. Sie lösen damit auch das gerade oben erwähnte Problem, das bei XML-Kommentaren auftritt. Die XML Schema-Kommentar-Elemente erscheinen als Kind-Elemente der dokumentierten XML Schema-Elemente und können daher auch bspw. mit XSLT automatisiert ausgelesen und den dokumentierten Strukturen zugeordnet werden.
Abbildung 9.1: XML Schema-Kommentar-Elemente
●●
Anmerkung als Eltern-Element: Das xs:annotation-Element bildet das ContainerElement der beiden möglichen Kommentar-Elemente xs:documentation und xs:appinfo. Beide können zusammen, getrennt und in verschiedener Reihenfolge und mehrfach auftreten. Inhalt: (appinfo | documentation)*
1
9
Vgl.: http://www.w3.org/TR/xmlschema-1/#cAnnotations
363
9. Dokumentation
●●
Anwendung: Für die Speicherung von maschinenlesbaren Anmerkungen besitzt das xs:appinfo-Element ein gemischtes Inhaltsmodell und ein Attribut namens source, in dem Verweise auf Applikationen oder Dateien erfolgen können. Mögliche Inhalte sollten alle Informationen sein, die von Anwendungen oder Parsern automatisch ausgelesen und verarbeitet werden, wobei die Verarbeitung nicht daraus bestehen sollte, die Dokumenation in einem anderen Format wiederzugeben, das von Menschen gelesen werden soll. Stattdessen könnte man hier SQL2-Befehle oder SVG-Elemente3 speichern, die nachher von anderen Anwendungen verarbeitet werden sollen.
Inhalt: ({any})*
●●
Dokumentation: Für die Speicherung von menschenlesbaren Anmerkungen besitzt das xs:documentation-Element ein gemischtes Inhaltsmodell und ein Attribut namens source, in dem Verweise auf Dateien mit weiteren menschenlesbaren Informationen gespeichert werden können. Zusätzlich kann man über das xml:lang-Attribut und den standardisierten Sprachwertvorgaben die Sprache des Dokumentationsbaustseins bestimmen. Inhalt: ({any})*
Der xs:annotation-Container kann in allen Elementen untergebracht werden und ersetzt somit die XML-Kommentare vollständig. Neben dieser Gemeinsamkeit bieten die hier vorgestellten Kommentare die Möglichkeit, einfachere automatische Extraktionen zu unterstützen als einfache XML-Kommentare. Dies liegt daran, dass ein xs:annotationContainer über die Eltern-Achse sehr leicht seinem übergeordneten Element zugeordnet werden kann, sodass in der Transformation sehr einfach herausgefunden werden kann, welches Element er eigentlich kommentiert. Dies ist bei XML-Kommentaren nur begrenzt möglich, da sie auf einer eigenen Achse liegen.
9 2 Standard: ISO 9075-1989 3 Informationen zum Standard: http://www.w3.org/Graphics/SVG/
364
9. Dokumentation
9. 1. 2. 1 Speicherung einfacher Textknoten Die einfachste Einsatzmöglichkeit von den XML Schema-Kommentaren ist die Speicherung einfacher Textknoten. In diesem Sinne ersetzen sie die XML Kommentare völlig, weisen aber die gerade genannten Vorteile auf, direkt ihrem übergeordneten Eltern-Elemente zugeordnet werden zu können. Im nächsten Beispiel ist zum Beispiel eindeutig, dass der jeweilige Kommentar tatsächlich genau das Element beschreibt, dessen Kind er ist. Bei XMLKommentaren ist es leicht möglich, sie vor oder nach der Deklaration aufzuführen, wobei dann nicht klar ist, welches Element sie eigentlich beschreiben wollen. Hier fehlt dann der Zuordnungsschüssel, der bei den XML Schema-Kommentaren über die Hierarchiebeziehungen sehr viel einfacher vorgegeben ist.
Globales Element | Einsatz in UmsatzTyp ... Minimalelement des Umsatzes ... 91_02.xsd : Einsatz von XML Schema-Kommentaren
Auch wenn man die Wahl seiner Syntax nicht von Editoren abhängig machen sollte, so werden typischerweise die XML Schema-Kommentare grafisch deutlicher und besser angezeigt als die XML-Kommentare. Hier wirkt sich aus, dass sie eindeutig zugeordnet werden können bzw. auch von der Programmautomatik als Dokumentationskommentare und nicht etwa als auskommentierte und damit wertlose Dokumentbereiche erkannt werden.
365
9
9. Dokumentation
Abbildung 9.2 gibt die Darstellung in Altova XMLSpy für das oben teilweise abgedruckte Dokument wieder.
Abbildung 9.2: Kommentare in Altova XMLSpy
9. 1. 2. 2 Speicherung von XHTML-Daten Eine weitere interessante Möglichkeit eröffnet sich über die Verwendung anderer XMLBereiche innerhalb der XML Schema-Kommentare. Hier ist insbesondere XHTML eine gute Wahl, da auf diese Weise sehr leicht eine Extraktion und eine überaus leichte Formatierung erreicht werden kann, nämlich durch eine einfache Übernahme der Elemente in den Ausgabestrom. Dadurch kann man schneller als mit einfachen Textknoten eine HTML-Ausgabedatei erzeugen, welche die gesamten Kommentare innerhalb einer Schema-Datei wiedergibt. Damit die Extraktion genauso einfach durchgeführt werden kann wie im Beispiel des in Abschnitt „Einsatz von Fremd-Attributen“ dieses Kapitels, ist der Einsatz eines Namensraums Voraussetzung, der die zusätzlichen Elemente auszeichnet. Er muss lediglich innerhalb des xs:schema-Element über das Standardattribut xmlns-Attribut mit oder ohne Präfix deklariert werden.
9
Im folgenden Beispiel tauchen die Kommentare des zurückliegenden Beispiels erneut auf, enthalten aber dieses Mal unterschiedliche XHTML-Elemente wie h1 oder p. Hierbei ist darauf zu achten, dass es nicht zulässig ist, Elemente zu öffnen und erst später wieder zu schließen. Man könnte beispielsweise auf die Idee kommen, aus den globalen Elementen
366
9. Dokumentation
eine Liste zu erzeugen, in der jeder Kommentartext in einem li-Container sitzen würde. Dies würde aber auch bedeuten, dass der erste Kommentar das geöffnete ul-Element und der letzte Kommentar das geschlossene ul-Element enthalten müsste. Die gesamte Datei würde damit das Kriterium der Wohlgeformtheit nicht erfüllen. Dies ist nicht möglich, da innerhalb der einzelnen Kommentar-Container auf Wohlgeformtheit geachtet wird und damit die gesamte Datei nicht wohlgeformt wäre. Hier könnte nur eine eigene Liste in jedem Kommentar-Element Abhilfe schaffen.
Globale Elemente
Globales Element | Einsatz in UmsatzTyp ... Globale komplexe Typen Globaler Typ mit Kind-Elementen Aufruf in ErfolgTyp
9
367
9. Dokumentation
Minimalelement des Umsatzes
....
91_03.xsd: Verwendung von XHTML
9. 1. 3. Einsatz von Fremd-Attributen Mit dem Wissen, dass die XML Schema-Kommentare ausschließlich für die Kommentierung genutzt werden und die einfachen XML-Kommentare eher für das Auskommentieren von nicht gewünschten Passagen zum Einsatz kommen sollten, kommt die Kritik an den vorhandenen Elementen. Wenn man sehr ausführliche Kommentare einfügt bzw. innerhalb von verschachtelten Elementen Dokumentationsinformationen mit einfügt, verlängert sich der Quelltext erheblich. Dies liegt daran, dass auch für einen einzeiligen Kommentar bereits zwei Container benötigt werden, sodass eine Kommentarzeile in XML-Form sofort zu mindestens drei Kommentarzeilen in der XML Schema-Syntax führt. Dies ist insoweit bedenklich, als dass die ohnehin schwer lesbaren Schema-Dokumente noch undurchschaubarer werden. Diesem Umstand abhelfen können so genannte „Fremd-Attribute“. Das Schema für XML Schema selbst ist insoweit offen, als dass für jedes Element Fremd-Attribute zulässig sind, die in den Passagen zur allgemeinen Syntax in diesem Buch eigens hervorgehoben werden. Sie stammen aus einem anderen Namensraum als dem der Schema-Datei, bedürfen demnach einer Qualifizierung und einer Namensraumangabe. Dann lässt sich in jedem beliebigen Element ein entsprechendes Dokumentationsattribut wie z. B. dok über die Namensraumangabe wie z. B. dok:dok nutzen und mit dem Kommentartext füllen. Mit Hilfe der Fremd-Attribute bleibt der Vorteil der genauen Zuordnungen von Kommentaren zu den einzelnen Elementen erhalten, und die Verlängerung des Quelltextes liegt lediglich innerhalb der Attributdeklaration, nicht aber im eigentlichen Inhalt von Elementen. Dies ist gerade für Elemente ein nützlicher Ausweg, die nur aufgrund der Kommentierung zu Container-Elementen werden müssen, da sie ansonsten leer wären.
9
Im folgenden Beispiel wurden daher die gerade über die XML Schema-Kommentare eingegebenen Dokumentationstexte über das erwähnte dok-Attribut im Namensraum dok ausgegeben.
368
9. Dokumentation
...
... 91_04.xsd: Verwendung von Fremd-Attributen
9. 2. Auslesen von Kommentaren Einige Programmiersprachen bzw. die Entwicklungsumgebungen gestatten es, in XML oder auch in einer anderen Syntax eingegebene Kommentare direkt auszulesen und zu einer Dokumentation zusammenzustellen, die das gesamte Programm umfasst und ständig mit den Quelltexten und den in ihnen enthaltenen Kommentaren abgeglichen und synchronisiert werden kann. Da XML Schema direkt im XML-Umfeld erstellt wird, erscheint es klar, dass eine ähnliche Möglichkeit auch genutzt werden sollte. Zudem besteht die Möglichkeit, selbst die Lösung vorzugeben, mit denen die Kommentare aus den einzelnen Dateien extrahiert werden sollen, sodass eine sehr große Flexibilität entsteht, die natürlich auch größere Anforderungen an die Entwickler nach sich zieht, da die diversen Kommentierungsmöglichkeiten auch unterschiedliche Anforderungen an die Datenextraktion stellen.
369
9
9. Dokumentation
Die Beispiele sind weitestgehend allgemein gehalten, was zwar das Verständnis des einen oder anderen Stylesheets erschweren könnte, doch andererseits den Vorteil mit sich bringt, dass die Beispiele in ähnlicher Form auch in anderen Zusammenhängen zum Einsatz kommen können. Folgende Vorlage wird in mehrere andere Stylesheets eingebunden und liefert die Fähigkeit, eine Zeichenkette zu vervielfältigen, was insbesondere bei der Textausgabe für Einzüge genutzt werden kann. Der Parameter grenze erwartet die Anzahl der einzufügenden bzw. zu kopierenden Instanzen der im Parameter wert übergebenen Zeichenkette. Diese ist standardmäßig ein Leerzeichen. Über den Parameter zaehler, der in den Beispielen selbst nicht gebraucht wird, sondern immer nur über seinen Standardwert 1 in die rekursive Verwendung der Vorlage eingeht, regelt man die Schrittweite der rekursiv modellierten FOR-Schleife.
textausrichtung.xslt: Standardvorlagen für Textausgabe
9. 2. 1. Auslesen von XML-Kommentaren Das verarbeitete Dokument ist 91_01.xsd.
9
Bei den XML-Kommentaren ist schwierig zuzuordnen, zu welchem Element sie gehören, d. h., ob sie das direkt Folgende kommentieren, das Container-Element, in dem sie platziert sind, oder sogar wie eine Bildunterschrift das Element, dem sie selbst folgen. Aus diesem Grund extrahiert das folgende Stylesheet aus den vorhandenen XML-Kommentaren nur die
370
9. Dokumentation
der oberen Ebenen, was über die Knotensauwahl im XPath-Ausdruck //comment() [local-name (parent::*) = ‚schema‘]“> bestimmt wird. Der entsprechende Kommentar wird in einer einfachen Textzeile ausgegeben, gefolgt von einer Zeile, die ihn unterstreicht. Die ihm direkt untergeordneten Elemente findet der XPath-Ausdruck //*[local-name (parent::*) = ‚schema‘], da auch hier wiederum auf das übergeordnete Eltern-Element xs:schema mit Hilfe seines lokalen Namens Bezug genommen wird. Für diese Elemente gibt man jeweils den lokalen Namen und – falls vorhanden – den Wert im Attribut name aus. Sollten sie noch weitere Elemente enthalten, findet sie der Ausdruck @* und gibt sie in einer eingerückten Liste in der Ordnung name wert aus.
9
# :
371
9. Dokumentation
92_01.xslt: Extraktion von XML-Kommentaren der obersten Ebene
Man erhält eine überschaubare zweifach eingerückte Liste, in der die Kommentare als Überschriften für die ihnen direkt folgenden Elemente dienen. Diese gibt man einfach eingerückt mit ihrem Typ und ihrem Namen aus, um sie hiernach noch einmal entlang ihrer Attributachse zu untersuchen und die gefundenen Attribute zweifach eingerückt auszugeben. Globale Elemente -----------------------------element Umsatz
# name: Umsatz # type: xs:decimal # nillable: false # abstract: false element Anrufe # name: Anrufe # type: xs:decimal # nillable: false # abstract: false
9
... Definition für Umsatztyp -----------------------------complexType UmsatzTyp # name: UmsatzTyp # mixed: false # abstract: false ErfolgTyp -----------------------------complexType ErfolgTyp
...
# name: ErfolgTyp # mixed: false # abstract: false
92_01.txt: Ausgabe in Textdatei
372
9. Dokumentation
9. 2. 2. Auslesen von XML Schema-Kommentaren in Textdatei Das verarbeitete Dokument ist 91_02.xsd. Die Zuordnungsproblematik, wie sie zuvor bei den einfachen XML Kommentaren durch die Beschränkung auf die oberste Ebene umgangen wurde, entsteht bei den XML Schema-Kommentaren gar nicht erst. Über die parent-Achse erhält man Zugriff auf ihr ElternElement, das seinen Namen über die XPath-Funktionen local-name() ohne und über name() mit Namensraum-Präfix preisgeben muss. Zudem kann man über die Attributachse des Eltern-Elements jedes einzelne Attribut untersuchen und erhält insbesondere über das name-Attribut eine klare Zuordnung, welcher Instanzdokumentbaustein hier modelliert wird. Dies ist das Grundprinzip des gesamten Stylesheets und stellt auch das Grundprinzip der anderen Verarbeitungsbeispiele von XML Schema-Kommentaren dar. Über den Test //xs:annotation findet man jeweils die annotation-Elemente im Dokument und gibt für alle, deren Eltern-Element gerade nicht das schema-Element ist, auch den Namen des Eltern-Elements aus. Dabei findet der Ausdruck local-name(parent::*) den Namen des Eltern-Elements, der Ausdruck parent::*/@name den Wert des name-Attributs des Eltern-Elements von annotation-Elementen und der Selbstaufruf über current() oder den Punkt „.“ schließlich den Wert für jedes documentation-Element. Da eine Textdatei ausgegeben wird, ist die Formatierung über z. B. HTML-Attribute nicht möglich und kann nur über Zeilenumbrüche, Sonderzeichen oder Leerzeichen (Einzüge, Einrückungen) erstellt werden. Die vorliegende Datei verwendet Zeilenumbrüche und die Einrückungen unter das jeweilige Eltern-Element, dessen Länge mit Hilfe der Funktion string-length() ermittelt wird und nach einer Zeichenkettenverknüpfung mit dem Wert im name-Attribut sowie dem Trennzeichen als Parameter grenze in den Aufruf des inkludierten Templates Einzug eingeht.
92_02.xslt: Auslesen von Kommentaren
Man erhält folgende einfache Textdatei, die ihre Übersichtlichkeit den Einrückungen und dem Einsatz der Kommentare auf oberster Ebene als Überschriften verdankt. Dies ist für den Kommentar „Globale Elemente“ der Fall, der direkt unterhalb des schema-Elements verwendet wurde und hier als Überschrift ohne Angabe des schema-Elements als sein eigenes Eltern-Element erscheint, während die anderen Kommentare ausdrücklich über „element“ oder „complexType“ ihr Eltern-Element angeben. Globale Elemente element | Umsatz: Globales Element | Einsatz in UmsatzTyp element | Anrufe: Globales Element | Einsatz in UmsatzTyp element | Kunden: Globales Element | Einsatz als erweitertes Element von UmsatzTyp complexType | UmsatzTyp: Globaler Typ mit Kind-Elementen Aufruf in ErfolgTyp Minimalelement des Umsatzes complexType | ErfolgTyp: Enthält Gesamt- und ProKopf-Daten element | Erfolguebersicht: Wurzelelement 92_02.txt: Extrahierte-Kommentarübersicht
9
374
9. Dokumentation
9. 2. 3. Auslesen von XML Schema-Kommentaren in HTML Das verarbeitete Dokument ist 91_02.xsd. Während bei der Erzeugung von Textdateien bereits einige Besonderheiten für die Formatierung der Ausgabe berücksichtigt werden müssen, wenn die Textdatei nicht besonders einfach und langweilig sein soll, entfällt dieses Problem bei der Erzeugung von HTML komplett. Allerdings hat man dann auch nicht mehr die Möglichkeit, die Datei in einem einfachen Texteditor zu verwenden, sondern benötigt stets einen Browser. Um die HTML-Datei zu erzeugen und nicht, wie im vorherigen Beispiel, global auf alle Anmerkungselemente zuzugreifen, verarbeitet die nächste Stylesheet-Datei das SchemaDokument der Reihe nach entlang seines Baums. Die Transformation stößt dabei der Ausdruck match=“/“ an, der den Wurzelknoten findet und für diesen das HTML-Grundgerüst ausgibt. Dann soll der XSLT-Prozessor über passende Vorlagen auswählen, die erneut über //xs:annotation für die annotation-Elemente im Dokument gelten. Einrückungen und Absätze erzeugen nun die h1 und h2 sowie die ul und li-Elemente in HTML. Die Auswahl der Knoten und Werte für die Angabe, zu welchem Elementtyp mit welchen Instanzdokumentnamen (erhältlich über das name-Attribut) es gehört, erfolgt dann über die gleichen Lokalisierungspfade und Bedingungen wie im vorherigen Beispiel: Dabei findet der Ausdruck local-name(parent::*) den Namen des Eltern-Elements, der Ausdruck parent::*/@name den Wert des name-Attributs des ElternElements von annotation-Elementen und der Selbstaufruf über current() oder den Punkt „.“ schließlich den Wert für jedes documentation-Element. Dokumentation
9
375
9. Dokumentation
92_03.xslt: Ausgabe von Kommentar-Textknoten in HTML
9 Abbildung 9.3: Ausgabe von Kommentar-Textknoten in HTML
376
9. Dokumentation
Man erhält als HTML-Datei bzw. im Browser die folgende Datei, in der das schema-Element selbst in h1 und die anderen Elemente in h2 ausgegeben werden. Für die einzelnen Kommentare erfolgt die Ausgabe in einer Liste.
9. 2. 4. Auslesen von XHTML nach HTML Das verarbeitete Dokument ist 91_03.xsd. Die Auswahl und Verarbeitung für die XHTML-Elemente hat eine Gemeinsamkeit mit den Fremd-Attributen, zeigt aber auch fundamentale Unterschiede, die in der Struktur von Element und Attribut an sich begründet liegen: Während für die Fremd-Attribute der Namensraum bei der Verwendung innerhalb der Schema-Datei obligatorisch ist, da diese Attribute gerade nicht durch das Schema für XML Schema deklariert sind, ist durch das gemischte Inhaltsmodell für das documentation-Element, vonseiten des Schemas für XML Schema jedes Kind-Element erlaubt. Dies erweist sich beim Einsatz als sehr praktisch, da man gerade keinen Namensraum angeben muss, während man die XHTML-Elemente verwendet. Dies verhält sich genau konträr zu Fremd-Attributen, die nur durch die Angabe ihres Namensraums innerhalb der Schema-Datei überhaupt verwendet werden können. Dennoch wurde in der Schema-Datei für das Beispiel, wie XHTML-Elemente innerhalb von documentation eingesetzt werden kann, stets ein Namensraum angegeben. Auf diese Weise kann man gleich bei der Verarbeitung explizit auf diese Elemente zugreifen bzw. gerade diese Elemente nicht verwenden. Die Problematik besteht nämlich darin, dass in documentation enthaltene Elemente logischerweise auch wiederum als Kind-Elemente gelten und die bisher so erfolgreich benutzten Lokalisierungspfade local-name(parent::*) (Name des Eltern-Elements) und parent::*/@name (Wert des name-Attributs des ElternElements) ins Leere bzw. in das falsche Eltern-Element laufen. Das Ergebnis kann – je nach Verschachtelung innerhalb der XHTML-Ausdrücke – documentation, annotation oder sogar ein XHTML-Element sein, also alles Elemente, die für die Beschreibung der Kommentare unnütz sind. Zwar bietet sich immer noch die Möglichkeit, über XPath-Ausdrücke mit entsprechender Komplexität über die ancestor-Achse zu versuchen, auf das Eltern-Element von annotation zuzugreifen, aber letztendlich einfacher ist es doch, über das Namensraumkonzept die Knotensätze voneinander zu trennen. Das Kernstück der Verarbeitung ist eine dreifache Schleife. Die äußere findet mit dem Ausdruck //following::* [local-name()=‘annotation‘] die einzelnen annotation-Ele-
377
9
9. Dokumentation
mente im Schema-Dokument; die mittlere findet mit dem Ausdruck xs:documentation jedes documentation-Element; und die innere findet schließlich mit dem Ausdruck dok:* jedes einzelne XHTML-Element, die alle mit diesem Namensraum ausgezeichnet sind. Die Verarbeitung der XML Schema-Daten erfolgt dann über die genannten „Funktionen“, während die Werte innerhalb der documentation-Elemente ohne ihren Namensraum in den Ausgabestrom geschrieben werden und so die Formatierung desselben über die bereits vorgegebenen XHTML-Elemente erfolgt.
Dokumentation
9
92_04.xslt: Auslesen von XHTML in HTML
Man erhält als Ergebnis eine HTML-Datei, die ihren Inhalt und die Auszeichnungen direkt aus den extrahierten Kommentarinformationen bezieht.
378
9. Dokumentation
Abbildung 9.4: Dokumentation in HTML
9. 2. 5. Auslesen von Fremd-Attributen Das verarbeitete Dokument ist 91_04.xsd. Ein Vorteil der Fremd-Attribute lag drin begründet, dass sie die Datei nicht übermäßig verlängern und letztendlich nur den eigentlichen Kommentartext in der Datei speichern. Dies wird mit einer Einschränkung erkauft: Während innerhalb eines annotation-Elements mehrere documentation-Elemente auftreten können und so weitere Untergliederungen in Form von XHTML-Absätzen oder auch durch Absätze in Textdateien eingerichtet werden können, muss der gesamte erklärende Text in das Attribut geschrieben werden. Dies ist natürlich ein Problem, da hier keine raffinierten Formate möglich sind, sodass man vermutlich geneigt ist, längere Texte in Form von Fließtext zu erfassen, die durch den größeren Umfang eine ähnlich hohe Genauigkeit erreichen wie ohne Absätze aneinander gereihte Stichpunkte. Auf diesen Umstand geht das vorliegende Stylesheet ein, indem es über die Einrückung hinaus, wie sie von der importierten Vorlage Einzug eingerichtet wird, auch noch einen Zeilenumbruch für zu lange Textstellen gestattet, wobei weitere Zeilen ebenfalls korrekt eingerückt sind.
379
9
9. Dokumentation
Diese spezielle Art der Formatierung leistet die Vorlage namens Zeilenausgabe, die rekursiv immer kürzere Ausschnitte aus dem ehemals komplett eingelesenen Attributinhalt rekursiv an sich selbst weitergibt. Bei jeder Iteration gibt man wiederum die Zeilenbreite der eingerückten Zeilen aus, bis schließlich alle Zeichen verarbeitet sind. Die einzelnen Attribute lassen sich sehr leicht über den XPath-Ausdruck //*[@dok:dok] auswählen, wobei die oben beschriebenen Lokalisierungspfade auf sich selbst verkürzt werden und nicht mehr die Eltern-Achse benutzen müssen, weil es sich um ein Attribut des für die Ausgabe zu bearbeitenden, dokumentierten Elements handelt. Mit dem Ausdruck local-name(.) findet man nun den Namen des kommentierten Elements, und mit @name erreicht man unmittelbar den Wert des name-Attributs des dokumentierten Elements, die beide in den Ausgabestrom geschickt werden.
9
380
9. Dokumentation
92_05.xslt: Ausgabe von Fremd-Attributen in Textform
381
9
9. Dokumentation
Man erhält folgendes Dokument, dessen Einrückung nun für alle Zeilen fünf Leerzeichen beträgt. Die Zeilenbreite der ausgegebenen Kommentarinhalte liegt bei 50. An der Stelle 50 wird jeweils die Zeichenkette auseinander gerissen (Silbentrennung wäre besonders schön, ist aber leider nicht verfügbar) und der Rest in die nächste Zeile geschrieben, bis auch hier die Zeilenbreite von 50 erreicht ist. element | Umsatz:
Globales Element, wird aufgerufen in UmsatzTyp element | Anrufe: Globales Element, wird aufgerufen in UmsatzTyp element | Kunden:
Globales Element, wird in Erweiterung zu UmsatzTyp
hinzugefügt complexType | UmsatzTyp:
Globaler komplexer Typ mt Minimalinhalt für Umsatz
datenstruktur complexType | ErfolgTyp: Globaler komplexer Typ mt Referenz von UmsatzTyp f ür Gesamt- und ProKopf-Umsatz, wobei für Gesamt zu sätzlich das Element Kunden aufgerufen wird element | Erfolguebersicht: Wurzelelement, enthält Erfolg-Elemente, die auf de m ErfolgTyp basieren 92_05.txt: Ausgabe in Textdate
9
382
DB-Datenmodellierung und XSLT-Transformation
10. DB-Datenmodellierung und XSLT-Transformation
10. DB-Datenmodellierung und XSLT-Transformation Nach der Darstellung der kompletten Syntax von XML Schema, verbunden mit Hinweisen auf allgemeine Dokumentmodellierungstechniken findet man auf der Landkarte von XML Schema noch einige Themen, die zu klein für ein eigenes Kapitel sind und zudem nicht in die bisher behandelten Themenkreise passen. Daher sammelt dieses Kapitel drei unterschiedliche Themen: die Modellierung von DB-Datenmodellen über die XML SchemaSyntax und die Transformation von XML Schema-Dokumenten.
10. 1. Datenmodellierung Da XML Schema einen großen Reichtum an Datentypen und darüber hinaus auch die Möglichkeit bietet, selbst eigene Datentypen zu entwickeln, liegt es nahe, anstatt SQL-Quelltext für die Beschreibung von Datenmodellen die Syntax von XML Schema zu verwenden. Dies ist zudem eine Option, die der Editor XMLSpy automatisch anbietet, wobei er über ADO1, den MS Access-Treiber oder ODBC2 direkt auf eine Datenbank zugreifen kann und aus den ausgewählten Tabellen entsprechende Elemente mit Kind-Elementen oder Attributen als Felder erzeugt. Für das vorliegende Beispiel wird das ohnehin schon in einer Oracle-Datenbank bereit stehende Datenmodell der RuhrFon GmbH verwendet. Es enthält die folgenden, in Abbildung 10.1 angegebenen Tabellen: ●●
GKUNDE für Daten von Geschäftskunden
●●
PKUNDE für Daten von Privatkunden, wobei sowohl für GKUNDE als auch für PKUNDE
sehr ähnliche Datenstrukturen vorliegen
10
1 Informationen zur Technik: http://msdn.microsoft.com/library/default.asp?url=/code/list/ado.asp 2 ���������������������������������������������������������������������������������������������������������� Informationen zur Technik: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odch06pr_2.asp
384
10. DB-Datenmodellierung und XSLT-Transformation
●●
TARIF für die Angaben zu den einzelnen Tarifen und ihren Preisen und Gültigkeiten
●●
MITARBEITER für die Daten der einzelnen Angestellten des Unternehmens
●●
RECHNUNG für die Speicherung der Rechnungen
●●
POSTEN für die Speicherung der einzelnen Einträge gemäß den Tarifen in einer Rech-
nung ●●
ANRUF für die Speicherung der Transaktionsdaten, die in diesem Fall Anrufe darstellen
Abbildung 10.1: Datenmodell der RuhrFon GmbH
10 385
10. DB-Datenmodellierung und XSLT-Transformation
Als Datenmodell in MS Visio (ebenfalls über ODBC importiert) hat es die abgebildete Gestalt, wobei die Pfeile zusätzlich die Verknüpfungen über die Primärschlüssel-Fremdschlüssel-Beziehung repräsentieren. Die Vorteile, die sich durch den Einsatz von XML Schema bei der Datenmodellierung ergeben, sind vor allen Dingen in der sehr allgemeinen Speicherung der Daten zu sehen. Anstatt proprietäre SQL-Befehle oder eine Grafik wie ein ER-Modell, OR-Modell oder eine vereinfachte Version von beiden wie das zuvor verwendeten Datenmodell aus MS Visio zu verwenden, erhält man mit einer XML Schema-Datei einen Textdatei, welche die Beschreibung der Feldnamen und ihrer Datentypen verwendet. Ein Vorteil gegenüber SQL besteht darin, dass auf die Besonderheiten der einzelnen Datenbanksysteme verschiedener Hersteller, die sich oft auch in der DDL-Syntax unterscheiden, keine Rücksicht genommen zu werden braucht. Ein weiterer Vorteil liegt darin, dass eine Textdatei und nicht etwa eine Grafik entsteht, die mit sehr einfachen Mitteln lesbar ist und kein spezielles Entwicklungswerkzeug erfordert. Ein letzter Vorteil besteht im Einsatz von XML, wobei hier die XML SchemaSyntax nur als Syntax für die Datenbeschreibung verwendet wird. Man könnte natürlich auch ein eigenes Vokabular mit solchen Elementen wie Tabelle und Feld verwenden, das wiederum mit einem Typ-Attribute standardisierte Datentypnamen enthält. Doch da XML Schema einen großen Reichtum an Datentypen bietet, die zudem sehr fein festgelegt und eingeschränkt werden können, erscheint der Aufwand, eine Schema-Datei zu entwickeln, die für die Abbildung von Datenmodellen nutzbar ist, wenig sinnvoll. Neben der Eignung von XML Schema für die Datenmodellierung ist die Verwendung von XML für die Datenmodellierung für Datenbanken insoweit sehr interessant, als dass man über entsprechende XSLT-Templates Dokumente mit unterschiedlichen Inhalten leicht in ein geeignetes SQL-Vokabular überführen kann. Da dieses Stylesheet zwar für jede Datenbank bzw. jede abweichende Syntax erstellt und zumindest auf sie ausgerichtet sein muss, entsteht zwar ein zusätzlicher Entwicklungsaufwand, der aber über die Mehrfachnutzung der Transformation von mehreren Dateien, die mal für das eine und mal für das andere Datenbanksystem erstellt werden, sich auf längere Sicht in schnellerer Transformationszeit von Datenmodellen niederschlägt. Da solche Entwicklungsumgebungen wie XMLSpy auch einen Automatismus anbieten, Datenmodelle in XML Schema-Syntax einzulesen und sogar wieder in eine Datenbank zurückzuschreiben bzw. die entsprechenden Tabellen im System anzulegen, kann hier sogar auf eine eigene Entwicklung von Transformationen verzichtet werden, solange kein reiner SQL-Quelltext aus der Schema-Datei erzeugt werden soll.
10 386
10. DB-Datenmodellierung und XSLT-Transformation
10. 1. 1. Datenmodellierung mit Elementen und Attributen Wie oben schon erwähnt, besteht selbstverständlich prinzipiell die Möglichkeit, eine eigene Schema-Datei zu entwickeln, in der die Tabellennamen, Datentypen und Einschränkungen in eigenen Beziehungen gespeichert sind. Dabei könnten auch weiterhin die Datentypen aus XML Schema so wie in jeder anderen Datei für das Element Feld übernommen werden. Hierbei würde man ein eigenes XML-Instanzdokument erstellen, das die Datenbankdaten enthält. Alternativ bieten sich allerdings auch die beiden folgenden sehr einfachen Möglichkeiten an, XML Schema direkt für diese Aufgabe zu verwenden: Anstatt eine Schema-Datei für Dokumente zu entwickeln, die Datenmodelle enthält, setzt man direkt eine Schema-Datei ein, deren Instanzdokumente quasi die in der Datenbank vorhandenen oder geplanten Datenstrukturen sind. Dies ist ein grundsätzlich anderer Ansatz, bei dem eine XML Schema-Datei zum ersten Mal selbst Inhalte enthält, die ansonsten nur in den bisher verwendeten Instanzdokumenten vorhanden waren.
10. 1. 1. 1 Felder als Elemente Eine erste Möglichkeit für die Abbildung von Datenstrukturen in einer Datenbank ergibt sich über die Konstruktion, die einzelnen Tabellenfelder als Kind-Elemente eines Elements zu definieren, das seinerseits die Tabelle definiert. So enthält folgender kurzer Ausschnitt die Definition der Tabelle ANRUF mit den oben in Abbildung 10.2 angegebenen Feldern als Kind-Elemente. Die jeweiligen Datentypen der Elemente gelten dann als Datentypen für die Datenbankfelder.
10 387
10. DB-Datenmodellierung und XSLT-Transformation
...
101_01.xsd: Verwendung von Elementen für Felder
Man erhält, wie Abbildung 10.2 zeigt, eine Reihe von einfachen Elementen, die untereinander in keiner hierarchischen Beziehung zueinander stehen und jeweils in flacher Form Felder in Form von Kind-Elementen enthalten.
Abbildung 10.2: Eltern-Elemente mit Kind-Elementen als Felder
10. 1. 1. 2 Felder als Attribute
10
Eine zweite Möglichkeit für die Abbildung von Datenstrukturen in einer Datenbank ergibt sich über die Konstruktion, die einzelnen Tabellenfelder als Attribute eines Elements zu definieren, das seinerseits die Tabelle definiert. So enthält folgender kurzer Ausschnitt die
388
10. DB-Datenmodellierung und XSLT-Transformation
Definition der Tabelle ANRUF mit den oben in der Abbildung angegebenen Feldern als Attributen. Die jeweiligen Datentypen der Attribute gelten dann als Datentypen für die Datenbankfelder.
... 101_02.xsd: Elemente mit Attributen als Felder
10. 1. 1. 3 Schema-Datei für DB-Strukturen Ein kurzes Beispiel soll noch einmal den Gedanken aufgreifen, der am Anfang der Überlegungen, wie XML Schema für die Datenmodellierung von Datenbanken genutzt werden kann, auftauchte: Man könnte ein Schema für Instanzdokumente entwickeln, die in geeigneten Elementen und Attributen ein DB-Schema festlegen. Ohne ein solches Schema aus dem Nichts heraus entwickeln zu müssen, lässt sich mit folgender Abfrage in Oracle eine komplette Übersicht über eine Tabelle (es sind alle DB-Objekte einsetzbar) in XML-Form erstellen. Dazu zählen sowohl Verwaltungsinformationen der internen Speicherstruktur wie
389
10
10. DB-Datenmodellierung und XSLT-Transformation
auch die Informationen, die bereits die zuvor benutzen XML Schema-Dokumente enthielten. set pagesize 0
set long 90000 SELECT DBMS _ METADATA.GET _ XML (‚TABLE‘,‘ANRUF‘,‘SCOTT‘)
FROM DUAL;
101_03.sql: Abfrage von Metadaten in XML-Format
Man erhält eine überaus lange Datei, die folglich auch zu einer überaus langen XML Schema-Datei führen wird, da eine fast unübersehbar große Anzahl von Elementen für die Datenspeicherung verbraucht wird. Eine Auswahl, in der die für die aktuelle Überlegungen interessanten Informationen enthalten sind, ist im folgenden Ausschnitt wiedergegeben. Zu beachten ist, dass die Namen der Schema-Objekte sowie ihrer abhängigen Elemente wie z. B. Feldnamen im Element NAME gespeichert werden. Dies gilt sowohl für das ElternElement TABLE _ T, das die allgemeinen Tabellendaten enthält, als auch für die einzelnen Spalten, die innerhalb eines COLS bzw. hier noch einmal in einem COL _ LIST _ ITEM Container untergebracht sind. Die Datentypen referenziert das Element TYPE _ NUM über den hier als Fremdschlüssel gebrauchten Primärschlüssel der Datentyptabelle. Weitere Einschränkungen können über Elemente wie LENGTH, PRECISION und SCALE angegeben werden. Dies entspricht solchen Fassetten wie length, fractionDigits oder totalDigits in der XML Schema-Syntax. ... ... SCOTT ANRUF ... TABLE
...
10 390
10. DB-Datenmodellierung und XSLT-Transformation
... ... 9 ...
... A _ NR 2 22 10 0 ...
... A_TYP 1 1 4 'p' ...
... A_VON
...
2 22 5 0 ... 101_03.xml: XML-Instanzdokument mit Datenmodellinformationen
Erstellt man ein Schema-Dokument, welches das gerade in einem Auszug wiedergegebene Intanzdokument validieren soll, erhält man ebenfalls eine fast unüberschaubar lange Datei.
391
10
10. DB-Datenmodellierung und XSLT-Transformation
Daher folgt wiederum nur ein Auszug des Bereiches, der gerade die Tabellen- und Spaltennamen sowie die Felddatentypen bestimmt, und auf die Verwaltungsinformationen für die Tabellenspeicherung wird verzichtet. Ersichtlich wird bereits hier, dass ganz anderes vorgegangen wird, um ein Datenmodell in XML abzubilden. Während zuvor XML Schema selbst als datenhaltendes Dokument zum Einsatz kam, benutzt man in diesem Fall ein Schema-Dokument, das ein Instanzdokument beschreibt, in dem verschiedene Elemente mit unterschiedlichsten Eigenschaften für eine Tabelle und ihre Spalten enthalten sind. Dadurch steigt natürlich im direkten Vergleich zur vorherigen Methode die Präzision, mit der die Eigenschaften der Tabelle beschrieben werden können. Dies erhöht gleichermaßen die Komplexität möglicher SQL-Befehle, die aus dieser Datei generiert werden könnten. So ist beispielsweise in unterschiedlichen Elementen auch die Möglichkeit gegeben, Bedingungen vorzugeben, die zu solchen SQL-Befehlen wie CONSTRAINT „BEGINN“ CHECK(A _ Beginn < A _ Ende) führen könnten, was natürlich in der XML Schema-Datei in Element- oder Attribut-Format überhaupt nicht denkbar wäre. Solche erweiterten Funktionalitäten erkauft man sich allerdings zwangsläufig mit genau der Erstellung einer eigenen Schema-Datei, die dann auf komplett andere Weise geparst werden muss. ...
...
101_03.xsd: Schema-Dokument für DB-Datenmodelle
Abbildung 10.3 soll den gerade in Textform abgedruckten Auszug noch einmal schematisch darstellen, wobei auch hier Kürzungen und Verkleinerungen des Ausschnitts notwendig waren, da gerade die grafische Aufbereitung ungeahnte Größen erreicht.
Abbildung 10.3: Hierarchiebeziehungen und Elementstruktur
Insgesamt lässt sich feststellen, dass man sich entscheiden muss, inwieweit die größere Präzision durch die Verwendung eines speziellen Schemas durch die Entwicklungszeit und -kosten desselben gerechtfertigt erscheint. Geht es nur um Tabellennamen, Feldnamen und ihre Datentypen, reicht die einfache Struktur einer XML Schema-Datei völlig aus. Erst wenn man Primärschlüssel, Schlüsselbeziehungen und natürlich Einschränkungen wie
10 393
10. DB-Datenmodellierung und XSLT-Transformation
CHECK-Bedingungen implementieren möchte, lohnt sich die Überlegung, auf eine eigene
Schema-Datei auszuweichen.
10. 1. 2. Transformation in SQL Hat man keine Entwicklungsumgebung zur Hand oder möchte man die Transformation von einer XML Schema-Datei in SQL selbst durchführen, gelingt dies über ein einfaches XSLT-Stylesheet, das in diesem Abschnitt für Elemente und Attribute, aber auch in einer Kombinationsform vorgestellt werden soll. Man erhält nach der Transformation jeweils ein einfaches SQL-Skript, das die Angaben in den beiden bereits verwendeten Schema-Dateien nutzt und Felder mit den im Dokument angegebenen Feldnamen sowie ihren im Dokument angegeben Datentypen erstellt. Dabei muss berücksichtigt werden, für welche Datenbank das SQL-Skript erstellt werden soll, damit die korrekten Datentypen ausgewählt werden können. In diesem Fall wird es sich stets um ein Skript handeln, das für den Einsatz in Oracle gedacht ist. Weitere Datenbanken lassen sich dann berücksichtigen, wenn man bspw. die Datentyperkennung in einem gesonderten Template unterbringt, das jeweils den gleichen Parameter erwartet – also in diesem Fall die übergebene Zeichenkette der in der XML Schema-Datei gefundenen Werte – und dieses Template über eine für jede Datenbank individuell konfigurierte Datei in die vorhandene Schema-Datei inkludiert. Alternativ bietet sich natürlich auch die Möglichkeit an, nicht für jede Datenbank eine neue, einzubindende Datei zu erstellen, sondern stattdessen in einem umfangreichen Template mit einem zusätzlichen Schaltparameter die unterschiedlichen Datenbanken voneinander zu unterscheiden. Beim Aufruf müsste dann die entsprechende Datenbank über einen standardisierten Parameterwert übergeben werden.
10. 1. 2. 1 Felder als Elemente
10
Im ersten Fall weist die XML Schema-Datei innerhalb der einzelnen Elemente, welche die Tabellen mit Hilfe ihres name-Attributs definieren, für jedes einzelne Feld in einer Tabelle ein Kind-Element auf. Die Tabellenelemente findet der Ausdruck // xs:element[parent::xs:schema], für den eine reihenweise Verarbeitung dieser Elemente angestoßen wird. In der Variablen aktuellesElement speichert man das gerade zu verarbeitende Element bzw. die gerade zu erstellende Tabelle, mit deren Hilfe dann über den Ausdruck //xs:element [ancestor::xs:element/@name=$aktuellesElement] jedes einzelne Kind-Element gefunden wird, das es dann zu verarbeiten gilt.
394
10. DB-Datenmodellierung und XSLT-Transformation
Diese Verarbeitung besteht zunächst aus einer Ausgabe innerhalb eines Klammerausdrucks, der für die Eingrenzung der Feldliste gebraucht wird. Der Name der zu erstellenden Spalte ergibt sich aus dem name-Attribut des jeweiligen Elements. Komplizierter ist die Erzeugung des Datentyps, da er bei der einfachen Verwendung von Datentypen in XML Schema als Wert des type-Attributs erscheint. Setzt man zur weiteren Einschränkung weitere Fassetten ein, befindet sich diese Angabe im base-Attribut des restriction-Containers, das wiederum innerhalb eines simpleType-Containers liegt. Weil die eigentliche Verarbeitung des im base- oder type-Attribut gefundenen Wertes gleich ist, kann man beide situativ mit Hilfe des Lokalisierungspfades @type | xs:simpleType/xs:restriction/@ base auswählen. Mögliche Einschränkungen sind im Standardfall ausschließlich Einschränkungen der Länge. Weitere Einschränkungen über Bedingungen wie CONSTRAINT „TYP“ CHECK(A _ Typ IN (‚g‘, ‚p‘) müssten noch in das Stylesheet eingebaut werden, indem man sich auf enumeration-Elemente bezieht und dieselben ausliest. Für die Länge allerdings ist die Extraktion sehr einfach, weil man hier über descendant::xs:maxLength/@ value jeweils innerhalb des maxLength-Elements das value-Attribut findet, indem genau der Wert gespeichert ist, der später im SQL-Quelltext innerhalb eines Klammerausdrucks als Typbeschränkung in den Ausgabestrom geschrieben wird. Unabhängig davon, welche Datentypangabe der Prozessor findet, übergibt man den gefundenen Wert schließlich an eine spezielle Vorlage, die den Wert mittels einer einfachen Fallunterscheidung untersucht und einen für die jeweilige Datenbank passenden Wert bestimmt und ausgibt. DROP TABLE “ ”;
CREATE TABLE “ ” (
10 395
10. DB-Datenmodellierung und XSLT-Transformation
” ”
);
,
(
) NUMBER
VARCHAR2
10 396
10. DB-Datenmodellierung und XSLT-Transformation
DATE
101_01.xslt: Transformation in SQL
Man erhält schließlich sehr einfachen, aber dennoch innerhalb der jeweiligen Datenbank wirkungsvollen SQL-Quelltext, der innerhalb einer DB-Sitzung unter Verwendung der Standardspeichereinstellungen die entsprechenden Tabellen erzeugt. ...
DROP TABLE „GKUNDE“;
CREATE TABLE „GKUNDE“ ( „G_NR“ NUMBER, „G_NAME“ VARCHAR2(200), „G_BRANCHE“ VARCHAR2(100), „G_STRASSE“ VARCHAR2(30), „G_PLZ“ NUMBER, „G_STADT“ VARCHAR2(30), „G_VORWAHL“ NUMBER, „G_TELNR“ NUMBER, „G_BEGINN“ DATE, „G_ENDE“ DATE ); DROP TABLE „MITARBEITER“; CREATE TABLE „MITARBEITER“ ( „M_NR“ NUMBER, „M_ANREDE“ VARCHAR2(5), „M_VORNAME“ VARCHAR2(20), „M_NACHNAME“ VARCHAR2(30), „M_STRASSE“ VARCHAR2(40), „M_HAUSNR“ VARCHAR2(5), „M_PLZ“ NUMBER, „M_STADT“ VARCHAR2(30), „M_VORWAHL“ NUMBER, „M_TELNR“ NUMBER,
10 397
10. DB-Datenmodellierung und XSLT-Transformation
);
„M_FUNKTION“ VARCHAR2(30)
... 101_01.sql: Einfaches SQL für Oracle
10. 1. 2. 2 Felder als Attribute Im zweiten Fall weist die XML Schema-Datei innerhalb der einzelnen Elemente, welche die Tabellen mit Hilfe ihres name-Attributs definieren, für jedes einzelne Feld in einer Tabelle ein Attribut auf. Die Tabellenelemente findet der Ausdruck // xs:element[parent::xs:schema], für den eine reihenweise Verarbeitung dieser Elemente angestoßen wird. In der Variablen aktuellesElement speichert man das gerade zu verarbeitende Element bzw. die gerade zu erstellende Tabelle, mit deren Hilfe dann über den Ausdruck //xs:element[ancestor::xs:attribute/@name=$aktuellesElement] jedes einzelne Attribut gefunden wird, das es dann zu verarbeiten gilt. Da für Attribute ebenfalls der Datentyp in einem type-Attribut oder bei Verwendung einer Einschränkung innerhalb eines simpleType- und dann im base-Attribut eines restriction-Containers angegeben wird, bleibt der gesamte Rest des zuvor für den Fall erstellten Stylesheets, dass Kind-Elemente die einzelnen Spalten angeben, erhalten. DROP TABLE “ ”;
CREATE TABLE “ ” (
” ”
10 398
10. DB-Datenmodellierung und XSLT-Transformation
);
,
...
101_02.xslt: Transformation in SQL
Aus der Tatsache, dass die für die Verarbeitung grundlegenden Strukturen für die KindElemente und Attribute gleich sind, lässt sich ein weiteres Stylesheet generieren, das für beide Fälle gleichermaßen gültig ist. Es enthält in einer umfangreichen ODER-Lokalisierung jeweils den passenden Pfad für den einen wie für den anderen Fall. 101_03.xslt: Transformation in SQL aus beiden Modellierungsformen
10. 1. 2. 3 Erweiterung um Primär- und Fremdschlüssel Um zu zeigen, dass auch Erweiterungen des bisher als vernünftig und effizient bewerteten Konzepts, direkt XML Schema für die Datenmodellierung von Datenbanken zu verwenden, möglich sind, sollen im folgenden Beispiel Primär- und Fremdschlüssel in die Datei integriert werden. Dabei drängen sich natürlich die ohnehin schon vorhandenen Strukturen zur Schlüsselerzeugung und Referenz auf, die von den beiden Schema-Komponenten xs:key und xs:keyref her bekannt sind. Dabei sind Überlegungen, in welchem Zusammenhang
399
10
10. DB-Datenmodellierung und XSLT-Transformation
die Schlüssel in XML Schema gelten bzw. was die Positionierung des Schlüssels für die Einzigartigkeitsprüfung innerhalb des Dokuments oder innerhalb der Gültigkeit eines Elements anbetrifft, hier völlig unwichtig. Da ein Schlüssel innerhalb einer Tabelle gültig sein muss bzw. nicht unterschieden wird, ob er innerhalb eines Elements oder eines Dokuments gültig ist, weil das XML Schema-Dokument keine Dokumente validieren soll, sondern ein wenig zweckentfremdet Datenmodelle beschreibt, ist es für die Verarbeitung mit XSLT besonders erstrebenswert, die Schlüssel an der gleichen hierarchischen Position im Dokument zu positionieren. Dabei können die Schlüssel entweder alle außen auf der obersten Dokumentebene platziert werden, wo sie deutlich und sichtbar alle zusammen stehen, was gerade bei umfangreichen Tabellenbeschreibungen interessant sein könnte. Es besteht allerdings auch die Möglichkeit, sie direkt bei den Elementen der obersten Ebenen zu platzieren, die ihrerseits die verschiedenen Tabellen beschreiben. Dies hilft nicht nur, die Schlüssel genau einer Tabelle zuzuordnen, sondern es wäre der Logik von XML Schema folgend der adäquate Platz. Weil gerade ein Schlüssel innerhalb einer Tabelle bzw. innerhalb eines Elements gültig sein soll, ist die Definition eines Schlüssels als direktes Kind-Element eines tabellenbeschreibenden Elements genau richtig. Die Schlüsselverweise der Fremdschlüssel werden dann ebenfalls hier positioniert und verweisen auf die entsprechenden Primärschlüssel der anderen Elemente bzw. Tabellen. Im folgenden Dokument sind zunächst für einen bestimmten Ausschnitt die unterschiedlichen Schlüssel definiert, wobei ein Schlüssel und sein zugehöriger Verweis gefettet gehalten sind. Es handelt sich dabei um ein Dokument, in dem die Felder durch Attribute dargestellt werden. Dies soll allerdings nachher bei der Verarbeitung keine Rolle spielen, was natürlich das Transformationsdokument zwar etwas umfangreicher, dafür allerdings universell einsetzbar macht. Insgesamt ist allerdings – sofern man die Transformation noch einmal selbst erstellen möchte – die Verwendung der Element-Form für die einzelnen Felder einfacher, da zum Wert im xpath-Ausdruck der xs:key- und xs:keyref-Elemente jeweils auch das @-Zeichen zur Navigation entlang der Attributachse gehört, was gleich extra berücksichtigt werden muss.
10
...
400
10. DB-Datenmodellierung und XSLT-Transformation
... ...
101_04-.xsd: Integration von Schlüsseln und Verweisen
Wie oben schon angedeutet, unterscheiden sich die beiden Dateiformen für die Verarbeitung der Schlüssel sehr viel deutlicher als für die Erstellung der Feld-Liste. Hier konnte ja durch eine einfache ODER-Verknüpfung sowohl der Fall, dass die Elemente in Attributen, wie auch der, dass sie in Elementen liegen, gelöst werden. Weil jedoch die Verlinkung innerhalb der XPath-Ausdrücke für Schlüssel und Verweise in ein Attribut hinein über die @-Achse verläuft, steht natürlich auch hier in jedem Attributwert des Attributs xpath an erster Stelle das die Achse angebende @-Zeichen. Mit //xs:element[parent::xs:schema] findet man zunächst wieder alle Eltern-Elemente, welche die Tabellen angeben. In Ergänzung zum bereits oben abgedruckten Style-
401
10
10. DB-Datenmodellierung und XSLT-Transformation
sheet, von dem hier aus Platzgründen nur die neuen Bereiche zu finden sind, unterscheidet der Ausdruck position()=last() and not(//xs:key[ancestor::xs:element/ @name=$aktuellesElement]), ob überhaupt Schlüsselelemente zu finden sind oder nicht. Ist dies nicht der Fall, wird die Verarbeitung wie zuvor mit dem Beenden des SQLQuelltextes für die gerade bearbeitete Tabelle fortgesetzt. Andernfalls findet der Ausdruck //xs:key[ancestor::xs:element/ @name=$aktuellesElement] alle Schlüsselelemente des aktuellen Tabellendefinitionselements, für die in einer Schleife mit dem gleichen Auswahlkriterium unterschieden werden muss, ob es sich beim Fundort des Schlüsselwortes um eine Attributachse oder um eine Elementachse handelt. Hier ist eine wichtige Einschränkung zu machen, die mit den Überlegungen weiter unten zusammenhängt: Dieses Stylesheet erwartet, dass im xpath-Ausdruck des xs:field-Elements genau das Attribut oder der Name des Elements zu finden ist, in dem der Schlüsselwert enthalten ist. Es darf also derzeit kein Punkt bzw. die current()-Funktion enthalten sein. In diesem Fall – so müsste man zusätzlich in einer Fallunterscheidung ergänzen – könnte nur zwangsläufig der Wert des xpath-Attributs des xs:selector-Elements den passenden Knoten liefern. Die Wertausgabe erfolgt dann zweigeteilt durch die Fallunterscheidung für die Attributachse über den Testausdruck starts-with(xs:field/@xpath, ‚@‘) mit Hilfe des Lokalisierungspfades substring(xs:field/@xpath, 2) für das xsl:value-of-Element und für die Element-Form mit Hilfe des sehr einfachen Lokalisierungspfades xs:field/@xpath im Standardfall. Für die Erzeugung von Fremdschlüsselbeziehungen folgt man dem gleichen Prinzip, indem zunächst auf die Existenz von xs:keyref-Knoten mit Hilfe des Ausdrucks not(// xs:keyref[ancestor:: xs:element / @name=$aktuellesElement]) hin getestet wird. Ist dies nicht der Fall, beendet man den SQL-Quelltext für diese Tabelle, wohingegen man im anderen Fall in einer Schleife die gleichermaßen mit //xs:keyref[ancestor:: xs:element / @name=$aktuellesElement] gefundenen Elemente der Reihe nach verarbeitet. Dabei gleicht diese Verarbeitung der gerade für die Primärschlüssel gefundenen Werte, was die XPath-Ausdrücke betrifft, wenn auch ansonsten andere Zeichenkettenkonkatenationen (Zusammensetzungen) notwendig sind, um den korrekten Ausgabestrom zu erzeugen.
10
Für die den Schlüsselverweisen zugehörigen Zieltabellen, die ja neben dem Auffinden und der Ausgabe der Schlüsselfelder ebenfalls notwendig sind, findet der Ausdruck // xs:element[xs:key/ @name=$schluessel]/@name“ die zugehörigen Namen der Eltern-Elemente bzw. aus SQL-Perspektive die benötigten Tabellennamen. Da die Referen-
402
10. DB-Datenmodellierung und XSLT-Transformation
zen in der Form tabellenname.spaltenname erfolgen müssen, schreibt das Stylesheet zunächst den gefundenen Tabellennamen (Wert des name-Attributs des Eltern-Elements vom gesuchten Schlüssel) in den Ausgabestrom, gefolgt vom ähnlich wie bei der Primärschlüsselausgabe behandelten Wert der Spaltennamen, in dem der Fremdschlüsselwert auffindbar ist.
... )
);
,
PRIMARY KEY(
”
10 403
10. DB-Datenmodellierung und XSLT-Transformation
”
”
”
”
)
);
, ),
FOREIGN KEY (
”
10 404
10. DB-Datenmodellierung und XSLT-Transformation
”
”
”
) REFERENCES “
”(
” ” ” ” )
);
),
10 405
10. DB-Datenmodellierung und XSLT-Transformation
101_04.xslt: Umwandlung von Primär- und Fremdschlüsseln
Man erhält das folgende, um die Fremdschlüsselbeziehungen ergänzte Ausgabedokument in der SQL-Syntax für Oracle. Wichtig für die Funktionsweise ist wie immer – wenngleich auf diesen Umstand die Dokumentation des XSLT-Dokuments nicht hingewiesen hat –, dass stets die Fälle berücksichtigt werden, dass mehrere Fremdschlüssel enthalten sind, nur einer oder auch keiner vorhanden ist. In Abhängigkeit von diesen Umständen ist entweder das Ende des SQL-Quelltextes (keine weiteren, der letzte oder gar kein Knoten gefunden) oder ein Komma auszugeben. DROP TABLE „TARIF“; CREATE TABLE „TARIF“ ( „T_NR“ NUMBER, „T_NAME“ VARCHAR2(20), … PRIMARY KEY(„T_NR“, „T_NAME“) ); DROP TABLE „POSTEN“; CREATE TABLE „POSTEN“ ( „P_NR“ NUMBER, „R_NR“ NUMBER, „T_NR“ NUMBER,
„P_SUMME“ NUMBER, PRIMARY KEY(„P_NR“), FOREIGN KEY („R_NR“) REFERENCES „RECHNUNG“(„R_NR“), FOREIGN KEY („T_NR“) REFERENCES „TARIF“(„T_NR“) ); DROP TABLE „MITARBEITER“; CREATE TABLE „MITARBEITER“ ( ...
10 406
„M_NR“ NUMBER,
„M_FUNKTION“ VARCHAR2(30),
10. DB-Datenmodellierung und XSLT-Transformation
PRIMARY KEY(„M_NR“) ); 101_04.sql: Ausgabe in SQL-Datei
10. 1. 2. 4 Alternative Modellierungen Da auf Grundlage dieser Dateien ohnehin im Normalfall keine Instanzdokumente validiert werden sollen, besteht natürlich die Möglichkeit, die Bedeutung der Syntax von XML Schema insoweit zu vernachlässigen, als dass man sich im Schlüsselverweis darauf bezieht, dass innerhalb der Schema-Datei sowohl Attribute wie auch Elemente als Feld-Repräsentanten Kind-Elemente desjenigen Elements sind, das die einzelne Tabelle definiert. So könnte man sich überlegen, dass man über einen Ausdruck in der Form //xs:element/*/ child::*[local-name()=‘attribute‘ or local-name()=‘element‘] in jedem Fall schon mal sämtliche Attribute oder Elemente findet, da sie ja Kind-Elemente des tabellenbeschreibenden Elements sind. Denn schließlich ist für die Schlüsseldefinition ja egal, ob es sich um ein Element oder um ein Attribut handelt, das als Schlüsselfeld in Betracht kommt. Mit einem erweiterten Ausdruck in der Form //xs:element[xs:key/@ name=‘TSchluessel1‘]/*/child::*[local-name()=‘attribute‘ or localname()=‘element‘]/@name finden sich z. B. alle Namen von Attributen der Tabelle TARIF, die den TSchluessel1 enthält. Als Vereinfachung würde sich nun anbieten, unabhängig
davon, ob im Instanzdokument ein Element oder ein Attribut als Schlüssel und damit als Ziel für einen Schlüsselverweis eingesetzt wird, nur den Wert im name-Attribut von Elementen und Attributen zu speichern, von denen die Felder repräsentiert werden. Für ein mögliches Instanzdokument ist dann die Syntax falsch, sodass die Gültigkeit nicht geprüft werden kann, solange man xs:key und nicht xs:unique verwendet, da ja die entsprechenden Elemente, auf die hier verwiesen wird, auch tatsächlich existieren müssen. Beim Einsatz von xs:unique allerdings wäre ein vermeintlich fehlerhaftes XML Schema-Dokument als Instanzdokument nicht tatsächlich fehlerhaft, da in einem Schema-Dokument mit Attributen als Feld-Repräsentanten die referenzierten Schlüsselfelder in den Attributen der tabellenbeschreibenden Elementen nicht vorhanden sein müssten. Es stellt sich allerdings grundsätzlich die Frage, ob aus der Tatsache, dass wahrscheinlich kein Instanzdokument mit Daten auf der Basis der definierten XML Schema-Datei erstellt wird, die gewagte Schlussfolgerung gezogen werden darf, dass fehlerhafte bzw. nicht genaue Definitionen in Kauf genommen werden sollten. Die typische Aufgabe solcher Schema-Dokumente ist natürlich das Erzeugen von SQL-Quelltext bzw. die Speicherung von
407
10
10. DB-Datenmodellierung und XSLT-Transformation
DB-Datenmodellen in anderer Form als einem ER- oder OR-Modell sowie bereits vorhandenem SQL-Quelltext, da eine Grafik nicht ohne entsprechende Zusatzwerkzeuge ausgelesen werden kann und der SQL-Quelltext womöglich nur mit einer bestimmten Datenbank konform geht. Dient also das Schema-Dokument wirklich nur diesen beiden Zwecken, kann die XML Schema-Syntax in größerem Stil missachtet werden. Solche Annahmen werden allerdings in Ausnahmefällen stets ad absurdum geführt. Ein anderer Einsatzbereich tut sich nämlich durch die Speicherung von Beispieldaten bzw. auch Daten mehrerer Tabellen in einem einzigen Dokument auf. Dadurch erhält man sofort ein Instanzdokument, in dem die ungültigen Verweise auf nicht existierende Attribute überflüssigerweise unangenehm ins Gewicht fallen. Neben der Tatsache, dass gerade ein ganz neuer Verwendungszweck dieser XML SchemaDateien, die Datenmodelle beschreiben, angegeben wurde, lässt sich vor allen Dingen der folgende Schluss ziehen: Auf der einen Seite lassen sich immer weitere Eigenschaften, die in SQL nützlich sind, in der XML Schema-Sytanx realisieren, aber man sollte auf der anderen Seite stets darauf achten, in Ausnahmefällen auch gültige Instanzdokumente für die in der Datenbank gespeicherten Realdaten zu erzeugen, und daher entweder immer für beide Formen (Feldrepräsentation durch Elemente oder Attribute) Transformationsdokumente entwickeln oder natürlich sich auf eine Variante festlegen und in dieser Dimension auch weitere Elemente integrieren.
10. 1. 2. 5 Zusätzliche SQL-Eigenschaften Eine ganz wesentliche SQL-Eigenschaft ist natürlich in großen Datenbanken die Angabe von Einschränkungen, wie sie in folgendem kurzen Auszug erscheinen: ... „A_TNR“ NUMBER(3) NOT NULL, „A_PREIS“ NUMBER(10, 2) NOT NULL, CONSTRAINT „BEGINN“ CHECK(A_Beginn < A_Ende), CONSTRAINT „ENDE“ CHECK(A_Ende > A_Beginn), CONSTRAINT „DAUER“ CHECK(A_Dauer > 0), CONSTRAINT „TYP“ CHECK(A_Typ IN (‚g‘, ‚p‘)), ...
10
PRIMARY KEY(„A_NR“))
Einige dieser Einschränkungen wie z. B. der eingeschränkte Wertebereich für die Spalte A _ Typ lassen sich leicht über die xs:enumeration-Fassette direkt über die Syntax
408
10. DB-Datenmodellierung und XSLT-Transformation
von XML Schema modellieren. Untere und obere Grenzen (sowohl eingeschlossene als auch ausgeschlossene) können ebenfalls in XML Schema mit dem Schrankenkonzept über {min|max}{In|Ex}clusive realisiert werden. Andere allerdings, wie die Überprüfungen auf bestimmte Werte hin, die aus Spalteninformationen bezogen werden, würden in jedem Fall verlangen, dass man eigene Elemente erstellt und diese in XML Schema z. B. über einen eigenen Namensraum integriert. Dies ist in den meisten Fällen nicht zulässig, wohl kann man aber Attribute aus einem anderen Namensraum verwenden, ohne die allgemeinen Regeln von XML Schema zu verletzten. Diese Attribute bedürfen lediglich der Möglichkeit, vorher eingegrenzte bzw. standardisierte Ausdrücke in der Form feldname operator feldname zu übernehmen. Die Transformation muss diese Ausdrücke dann in der im Dokument gefundenen Reihenfolge innerhalb eines CHECK(-ausgelesener Inhalt-)-Ausdrucks wieder in den Ausgabestrom schreiben. Problematisch wäre die Angabe mehrerer Bedingungen, da jeweils drei Attribute zu einer Gruppe zusammengefasst werden müssten. Einfacher wird es, wenn man akzeptiert, dass die Angaben im Grunde genommen für XML Schema sowieso keine Bedeutung gewinnen können, da sie simple Textinhalte von Attributen darstellen und man letztendlich die gesamte zusätzliche Bedingungen als Attributwert speichern könnte. Daraus ergibt sich dann direkt der Wert für den Eintrag in SQL.
10. 2. XML Schema und Datenbanken XML und Datenbanken scheinen auf den ersten Blick konkurrierende Speichermöglichkeiten für strukturierte Daten zu sein. Viele glauben sogar, dass man sich zwischen XML und Datenbanken entscheiden müsste. Nur in Fällen, in denen eine Datenbank aufgrund sehr geringer Datenmenge nicht notwendig ist und man sich sozusagen eine Lösung auch mit einfachen Textdateien vorstellen könnte, ist dies tatsächlich so. Es hat sich stattdessen vielmehr herausgestellt, dass XML gut in Datenbanken integriert werden kann und bspw. XML Schema als besonders aufwändige Technik genutzt werden kann, um komplexe Datentypvorgaben für XML-Spalten oder –Variablen zu entwickeln. Als Beispielsystem betrachten wir in diesem Abschnitt Oracle und MS SQL Server, die jeweils einen eigenen XML-Datentyp besitzen und viele XML-Standards in SQL und ihren SQLErweiterungen unterstützen.
10 409
10. DB-Datenmodellierung und XSLT-Transformation
10. 2. 1. Einführung Dieser Abschnitt möchte nur einige allgemeine Vorbemerkungen geben, warum die Kombination von XML und Datenbanken für die Anwendungsentwicklung notwendig ist. Zwei wesentliche Aspekte bei der Nutzung von XML in Zusammenhang mit einer Datenbank sind die folgenden: ●●
Import-/Export-Schnittstellen können notwendig sein, weil andere Systeme bestimmte Datenausschnitte der exportierenden Datenbank benötigen, oder weil die eigene Datenbank als Ziel für solche Daten vorhanden ist. Dies können genauso Buchungs- und Reservierungssysteme wie Untersuchungs- und Analysesysteme sein, die auf Basis mehrerer Datenbanken erstellt werden, die wiederum möglicherweise sogar verschiedene Hersteller zum Hintergrund haben.
●●
Direkte Speicherung von XML oder Zerlegung von XML in relationale Daten kann sinnvoll sein, wenn komplexe Nachrichten im Rahmen von Transaktionen mit anderen Systemen ausgetauscht werden und deren Inhalt dauerhaft gespeichert werden soll. Hier ist es dann möglich, sich zu entscheiden, ob man XML-Daten bei Bedarf dynamisch erstellt und sie beim Speichervorgang relational zerlegt oder ob sie im jeweiligen XMLDatentyp der Datenbank oder sogar in eine native XML-Datenbank in einer Ordnerstruktur gespeichert werden.
Beide Datenbanksysteme bieten einen eigenen XML-Datentyp, der für die Speicherung von XML-Daten in Spalten, Variablen und Prozedur-/Funktionsparameter genutzt werden kann. Die folgende Gegenüberstellung gibt einen kurzen Überblick über die Fähigkeiten der beiden Datenbanken und zeigt, an welchen Stellen Unterschiede liegen.
Bereich
Oracle
MS SQL Server
XML-Datentyp Direkte Speicherung Validierung mit XML Schema XML-Bearbeitung
Ja, XMLType Ja Ja
Ja, XML Ja Ja
Mit PL/SQL und Java Unterstützung für DOM, XSLT durch PL/SQL Weitere Pakete für XMLVerarbeitung in PL/SQL Ja
Mit .NET T-SQL bietet nicht die Werkzeuge wie PL/SQL
XPath und XQuery
10 410
Ja
10. DB-Datenmodellierung und XSLT-Transformation
Bereich
Oracle
XML-Erzeugung bei Abfrage Verschiedene alternative Werkzeuge sind umgesetzt. Native Webservices Ja XML Schema Umfangreiche Unterstützung bei Integration und Entwicklung
MS SQL Server Verschiedene alternative Werkzeuge sind umgesetzt. Ja Unterstützung zur allgemeinen Verwendung. Aufgrund von Unterschieden bei der XML-Umsetzung nicht die gleiche Bedeutung wie bei Oracle.
Vergleich zwischen Oracle und MS SQL Server
10. 2. 2. Oracle Oracle bietet, wie die Tabelle gerade gezeigt hat, eine umfangreiche Fülle an Techniken für die Speicherung, Zerlegung, Erzeugung und Verarbeitung von XML-Daten. Zentral ist dabei der Datentyp XMLType, für dessen erfolgreichen Einsatz es mehrere umfangreiche PL/SQL-Pakete gibt. Wir konzentrieren uns in diesem Abschnitt auf den Themenbereich XML Schema und hier wiederum auf eine kurze Darstellung der wichtigsten Aspekte. Weitere Informationen finden Sie in unserem Buch „Oracle – PL/SQL und XML“ (ebenfalls von Comelio Medien).
10. 2. 2. 1 XML Schema registrieren, verwalten und verwenden Für die XML-Datenbank und auch zur Verwendung von XML Schema für die Validierung von XMLType-Daten steht das Paket DBMS _ XMLSCHEMA bereit. Es bietet eine Hand voll an Unterprogrammen zur Verwaltung von Schema-Dokumenten. Die XML Schema-Dokumente werden selbst in der nativen XML-Datenbank in einer Ordnerstruktur gespeichert. Mit den folgenden Unterprogrammen verwaltet man XML Schema-Dokumente in der XMLDatenbank. ●●
registerSchema(): Registriert das angegebene XML Schema in der XML-Datenbank.
Es kann dann benutzt werden, um Dokumente zu speichern, die durch das Schema validiert werden, oder um Sichten anzulegen, deren Daten dem XML Schema folgen. Folgende Parameter sind vorhanden:
10 411
10. DB-Datenmodellierung und XSLT-Transformation
schemaURL (IN) enthält die URL, die das Schema-Dokument eindeutig identifiziert. schemaDoc (IN) ist ein gültiges XML Schema-Dokument. local (IN) gibt an, ob das Schema lokal oder global (für alle Benutzer) vorliegen soll. Standardmäßig werden Schemata lokal unter /sys/ schemas/ ‚http://www.ruhrfon.biz/mitarbeiterliste.xsd‘,
gentypes => FALSE, genbean => FALSE, gentables => FALSE, schemadoc => XMLType(‚ ... ‘));
/* DBMS_XMLSCHEMA.DeleteSchema( schemaurl => ‚http://www.ruhrfon.biz/mitarbeiterliste.xsd‘, delete_option => DBMS_XMLSCHEMA.DELETE_CASCADE_FORCE); */ END; 102_02.sql: Registrieren eines XML Schemas
10 414
10. DB-Datenmodellierung und XSLT-Transformation
Das registrierte XML Schema kann für die Definition von XML-Spalten, Variablen/Parametern oder sogar Tabellen und Sichten zum Einsatz kommen. Im nächsten Beispiel folgen verschiedene Konzepte, die jeweils für sich genommen bereits eigene Kapitel füllen könnten. Zunächst erstellt man die Tabelle maliste _ x1, welche eine so genannte XMLType-Tabelle auf Basis von dem gerade registrierten XML Schema darstellt. Sie akzeptiert ausschließlich zu diesem Schema passende Daten und speichert auch keine anderen Daten. Sie hat eine Spalte mit dem unschönen Standardnamen sys _ nc _ rowinfo$. CREATE TABLE maliste_x1 OF XMLTYPE XMLSCHEMA „http://www.ruhrfon.biz/mitarbeiterliste.xsd“ ELEMENT „Mitarbeiterliste“;
102_03.sql: Erstellung einer XMLType-Tabelle
Die Tabelle füllt man dann über zwei unterschiedliche Techniken. Eine dritte – nämlich der Einsatz einer XMLType-Variablen – folgt später noch. Man kann sehr leicht aus relationalen Daten über SQL XML-Daten erstellen, indem man die sogenannten SQL/XML-Funktionen einsetzt. Dies ist ein ISO-Standard, der in Oracle und bspw. auch in IBM DB2 umgesetzt ist. Die Funktion XMLElement() erstellt ein XML-Element; XMLAttributes() kann mehrere Attribute erstellen; XMLForest() kann in analoger Syntax mehrere Geschwister-Elemente erstellen; und XMLAgg() gruppiert Elemente (teilweise ist zusätzlich GROUP BY notwendig). Die Abfrage liefert wohlgeformtes XML, das darüber hinaus auch noch gültig für das XML Schema ist und daher in der Tabelle gespeichert werden kann. INSERT INTO maliste_x1 VALUES ( (SELECT XMLElement(„Mitarbeiterliste“, XMLAgg( XMLElement(„Mitarbeiter“, XMLElement(„Name“, XMLAttributes(M_Anrede AS „Anrede“), XMLForest(M_Vorname AS „Vorname“, M_Nachname AS „Nachname“) ), XMLElement(„Funktion“, M_Funktion) ) )) AS MaListe FROM mitarbeiter WHERE M_Nr < 20) );
102_03.sql: XML-Erstellung über SQL/XML-Funktionen
415
10
10. DB-Datenmodellierung und XSLT-Transformation
Eine einfachere, aber wenig beeindruckende Alternative, ist es, XML-Zeichenketten direkt im als Konstruktor fungierenden XMLType-Schlüsselwort vorzugeben. So fügt man über die vorherige Abfrage 19 Datensätze aus der MITARBEITER-Tabelle als einen einzigen XMLDatensatz und nun noch einen weiteren Datensatz ein. Damit noch vor dem eigentlichen Speichervorgang auf Schema-Gültigkeit geprüft wird, ergänzt man den XMLType um den Methodenaufruf createSchemaBasedXML(). Dies erzeugt typisiertes XML. In einer Variablen bspw. könnte man dann nur gültige Daten speichern. INSERT INTO maliste_x1 VALUES ( XMLType( ‚
Marco Scheffchen Geschäftsführer ‘ ).createSchemaBasedXML(‚http://www.ruhrfon.biz/ mitarbeiterliste.xsd‘) );
-- Abfragen SELECT sys_nc_rowinfo$ AS MaListe FROM maliste_x1;
102_03.sql: Verwendung einer XMLType-Tabelle
10. 2. 2. 2 XMLType-Datentyp und seine Methoden Es stehen für die Arbeit mit XML Schema die folgenden Unterprogramme zur Verfügung. Man kann sie direkt an solchermaßen typisierten Variablen, Spalten oder Parametern verwenden. Teilweise gibt es auch zusätzliche SQL-Funktionen mit ähnlicher Funktionalität. In einer ersten Gruppe befinden sich Methoden, die XML Schema berücksichtigen oder nicht berücksichtigen.
10 416
10. DB-Datenmodellierung und XSLT-Transformation
●●
createSchemaBasedXML(): Erzeugt eine XMLType-Instanz mit Schema-Verknüp-
fung.
MEMBER FUNCTION createSchemaBasedXML( schema IN varchar2 := NULL )
RETURN XMLType
●●
createNonSchemaBasedXML(): Erzeugt eine XMLType-Instanz ohne Schema-Ver-
knüpfung.
MEMBER FUNCTION createNonSchemaBasedXML RETURN XMLType
Eine zweite Gruppe verwendet ein angemeldetes XML Schema für die Validierung und liefert/setzt den Gültigkeitsstatus einer XMLType-Instanz. ●●
schemaValidate(): Validiert die Eingabedaten einer XMLType-Instanz auf Basis ei-
nes XML Schemas.
MEMBER PROCEDURE schemaValidate
●●
isSchemaValidated(): Prüft, ob die XMLType-Instanz validiert wurde. MEMBER FUNCTION isSchemaValidated RETURN number
●●
setSchemaValidated(): Setzt das positive Validierungsergebnis von vorneherein
fest, um eine Validierung zu verhindern.
MEMBER PROCEDURE setSchemaValidated(flag IN BINARY_INTEGER := 1)
●●
isSchemaValid(): Prüft, ob die XMLType-Instanz gültig ist. MEMBER FUNCTION isSchemaValid( schemaurl IN VARCHAR2 := NULL, elem IN VARCHAR2 := NULL) RETURN number
Eine dritte Gruppe liefert nützliche Informationen bei einem verwendeten XML Schema wie den Status, ob ein XML-Dokument mit einem XML Schema verknüpft ist oder die URL des Schemas. ●●
isSchemaBased(): Liefert 1 zurück, wenn die XMLType-Instanz auf einem Schema
basiert, oder 0, wenn sie allein steht.
MEMBER FUNCTION isSchemaBased RETURN number
10 417
10. DB-Datenmodellierung und XSLT-Transformation
●●
getSchemaURL(): Liefert die XML Schema-URL, wenn eine vorhanden ist. MEMBER FUNCTION getSchemaURL RETURN varchar2
●●
getRootElement(): Liefert das Wurzelelement oder NULL bei einem Fragment. MEMBER FUNCTION getRootElement RETURN varchar2
●●
getNamespace(): Liefert den Namensraum des Wurzelelements eines schema-ba-
sierten Dokuments.
MEMBER FUNCTION getNamespace RETURN varchar2
Für das nächste Beispiel erstellt man eine Tabelle, die weniger beeindruckend als die vorherige ist. Sie enthält eine XMLType-Spalte neben anderen Spalten, die durch „herkömmliche“ Datentypen eingeschränkt sind. Die einfachste Form einer solchen Spalte stellt untypisiertes XML dar. So eine Spalte prüft nur auf Wohlgeformtheit und würde sich bspw. in einem Import-Szenario eignen, in dem zunächst eingehende Daten zur späteren Prüfung erst einmal gespeichert werden. Im aktuellen Fall folgt allerdings der Hinweis, dass die XMLType-Spalte sich auf ein bestimmtes XML Schema bezieht. CREATE TABLE maliste_x2 ( MAL_Nr NUMBER, MAL_Datum DATE, MAL_Inhalt XMLType) XMLTYPE COLUMN MAL_Inhalt ELEMENT „http://www.ruhrfon.biz/mitarbeiterliste.xsd #Mitarbeiterliste“; 102_04.sql: Tabelle mit XMLType-Spalte und weiteren Spalten
Um auch in dieser Tabelle XML-Daten zu speichern, erstellen wir als Alternative zunächst eine XMLType-Variable, welche sich auf das registrierte XML Schema bezieht. Sie wird über SELECT...INTO und die SQL /XML-Funktionen mit dem passenden XML gefüllt und schließlich in einem INSERT-Befehl genauso verwendet wie alle anderen Variablen bzw. Ausdrücke. Allerdings prüft man zunächst, ob die Regeln aus dem XML Schema auch für die abgerufenen Daten gelten, bevor die Einfügeoperation durchgeführt wird. DECLARE v_Mitarbeiterliste XMLType; BEGIN
10 418
10. DB-Datenmodellierung und XSLT-Transformation
-- Daten laden SELECT XMLElement(„Mitarbeiterliste“, XMLAgg(
XMLElement(„Mitarbeiter“,
XMLElement(„Name“, XMLAttributes(M_Anrede AS „Anrede“), XMLForest(M_Vorname
AS „Vorname“,
M_Nachname AS „Nachname“) ), XMLElement(„Funktion“, M_Funktion) )
)) AS MaListe INTO v_Mitarbeiterliste FROM mitarbeiter;
v_Mitarbeiterliste := v_Mitarbeiterliste. createSchemaBasedXML(
‚http://www.ruhrfon.biz/mitarbeiterliste.xsd‘);
-- XML-Daten validieren ... v_Mitarbeiterliste.schemaValidate(); IF v_Mitarbeiterliste.isSchemaValidated() = 1 THEN -- ... und gemeinsam mit anderen Daten einfügen INSERT INTO maliste_x2 VALUES (1, ‚01.05.2004‘, v_Mitarbeiterliste ); END IF; END; 102_04.sql: Verwendung einer XMLType-Variable
Für eine als XMLType angegebene Spalte stehen wie auch für Variablen oder Parameter innerhalb von PL/SQL verschiedene SQL-Funktionen zur Validierung mit XML Schema (XMLIsValid()), zur Abfrage mit XPath oder XQuery (extract() und existsNode()) oder auch zur Transformation mit XSLT (XMLTransform()) zur Verfügung. SELECT Mal_Nr, Mal_Inhalt FROM maliste_x2;
102_04.sql: Abfragen einer XML-Spalte
10 419
10. DB-Datenmodellierung und XSLT-Transformation
10. 2. 2. 3 Data Dictionary-Sichten Eine Reihe von Sichten informieren über vorhandene XML Schema-Dateien. Sie werden kurz aufgelistet. Wie bei anderen Sichten auch erfolgt bei den Sichten, die das Wort USER im Namen tragen, eine automatische Filterung nach dem angemeldeten Benutzer. Die Spaltennamen sind leicht verständlich. ●●
USER _ XML _ SCHEMAS: Alle registrierten XML Schema-Dokumente in Besitz des Be-
nutzers. ●●
ALL _ XML _ SCHEMAS: Alle registrierten XML Schema-Dokumente, die vom aktuellen
Benutzer genutzt werden können. ●●
USER _ XML _ TABLES: Alle XMLType-Tabellen in Besitz des aktuellen Benutzers.
●●
ALL _ XML _ TABLES: Alle XMLType-Tabellen, die vom aktuellen Benutzer genutzt
werden können. ●●
USER _ XML _ TAB _ COLS: Alle XMLType-Tabellenspalten in den Tabellen des aktu-
ellen Benutzers. ●●
ALL _ XML _ TAB _ COLS: Alle XMLType-Tabellenspalten, die vom aktuellen Benutzer
genutzt werden können. ●●
USER _ XML _ VIEWS: Alle XMLType-Sichten in Besitz des aktuellen Benutzers.
●●
ALL _ XML _ VIEWS: Alle XMLType-Sichten, die vom aktuellen Benutzer genutzt wer-
den können. ●●
USER _ XML _ VIEW _ COLS: Alle Spalten von XMLType-Sichten in Besitz des aktuellen
Benutzers. ●●
ALL _ XML _ VIEW _ COLS: Alle Spalten von XMLType-Sichten, die vom aktuellen Be-
nutzer genutzt werden können.
10
Ein Startpunkt bei der Verwendung der Sichten kann bspw. SELECT table _ name, xmlschema, element _ name FROM user _ xml _ tables; sein, der die Speichertabellen von XML Schema-basierten Daten, die URL des XML Schemas und das Wurzelelement angibt.
420
10. DB-Datenmodellierung und XSLT-Transformation
10. 2. 3. MS SQL Server Der MS SQL Server bietet, wie die Tabelle zuvor gezeigt hat, eine umfangreiche Fülle an Techniken für die Speicherung, Zerlegung, Erzeugung und Verarbeitung von XML-Daten. Da T-SQL nicht so umfangreich ist wie PL/SQL in Oracle, ist der Funktionsumfang geringer. Allerdings sind einige Techniken syntaktisch viel einfacher gelöst. Zentral ist dabei der Datentyp XML, für dessen erfolgreichen Einsatz es verschiedene Prozeduren und Funktionen gibt. Wir konzentrieren uns in diesem Abschnitt auf den Themenbereich XML Schema und hier wiederum auf eine kurze Darstellung der wichtigsten Aspekte. Weitere Informationen finden Sie in unserem Buch „MS SQL Server –XML und SOAP Web Services“ (ebenfalls von Comelio Medien).
10. 2. 3. 1 XML Schema registrieren und verwalten Um ein XML Schema zu speichern, welches aus einer Zeichenkette oder einer Datei über die Anweisung OPENROWSET eingelesen wird, verwendet man einen speziellen CREATEBefehl. Neben dem zu erwartenden Begriff XML SCHEMA enthält er zudem auch noch COLLECTION, da es möglich ist, mehrere XML Schema-Dokumente in einem, d. h. mehrere xs:schema-Elemente in einer Sammlung, zu besitzen. Im Normalfall dürfte man allerdings unter einem Namen in der Datenbank nur ein einziges XML Schema und nicht gleich eine ganze Sammlung von ähnlichen Dokumenten speichern. Im Parameter sql _ identifier trägt man einen Namen ein, unter dem dieses XML Schema dann verfügbar sein wird, während man im optionalen Parameter relational _ schema das Datenbank-Schema eintragen kann. Sollte dieser Parameter fehlen, wird das XML Schema einfach im Standardschema gespeichert. CREATE XML SCHEMA COLLECTION [ . ]sql_identifier AS Expression
Ist ein XML Schema gespeichert, besteht die Möglichkeit, es nicht nur zu löschen und neu zu erstellen, sondern auch zu ändern. Dabei lässt sich eine neue Komponente zu einem bestehenden XML Schema oder gleich ein ganz neues XML Schema zu einer Sammlung hinzufügen. Die letzte Möglichkeit dürfte in den meisten Fällen nicht so häufig sein, sofern keine Sammlungen mit mehreren XML Schema-Angaben genutzt werden. Als Parameter enthält relational _ schema wieder das DB-Schema, in dem sich nun in diesem Fall das bereits vorhandene XML Schema befindet, welches über den verpflichtenden Parameter sql _ identifier angesprochen werden kann. An das Schlüsselwort ADD schließt sich
421
10
10. DB-Datenmodellierung und XSLT-Transformation
dann genauso ein XML Schema an wie bei der CREATE-Anweisung. Sofern ein vorhandenes XML Schema aktualisiert werden soll, enthält es das gleiche xs:schema-Element. Sofern dagegen ein neues XML Schema in der Sammlung angehängt werden soll, ist dies ein neues xs:schema-Element. ALTER XML SCHEMA COLLECTION [
relational_schema. ]sql_identifier ADD ‚Schema Component‘
Schließlich möchte man auch noch ein einmal in der Datenbank gespeichertes XML Schema löschen können. Dies ist gerade auch dann notwendig, wenn der ALTER-Befehl für eine grundlegende Änderung nicht mehr ausreicht und es stattdessen einfacher ist, das XML Schema zu löschen und geändert neu zu speichern. In diesem Fall muss natürlich ausdrücklich berücksichtigt werden, dass Objekte, die das XML Schema referenzieren, eine Löschung verhindern. DROP XML SCHEMA COLLECTION [ relational_schema. ]sql_identifier
Um alle drei Anweisungen zu zeigen, soll das folgende sehr kurze Datenmodell in XML Schema-Syntax in der Datenbank gespeichert werden. Da es sich dabei letztendlich um eine XML-Datei handelt, kann man eine solche Datendefinition sowohl als Zeichenkette (was nun für ein Beispiel einfacher ist) wie auch aus einer Textdatei laden. Die Regeln der XMLBearbeitung in T-SQL bleiben allesamt erhalten. Auch wenn ein XML Schema in der Lage ist, andere XML-Daten zu beschreiben und man durch eine solche Angabe Daten validieren kann, so handelt es sich doch nur um eine XML-Datei. In der Datei 102_05.sql wird zunächst ein Tabelle mit den Mitarbeitern der RuhrFon GmbH angelegt und in diese Tabelle 20 Datensätze eingefügt. CREATE TABLE Mitarbeiter ( „M_NR“ decimal(4,0) NOT NULL, „M_ANREDE“ nvarchar(5),
„M_VORNAME“ nvarchar(20), „M_NACHNAME“ nvarchar(30), „M_FUNKTION“ nvarchar(30), CONSTRAINT PK_MNr PRIMARY KEY („M_NR“) ); 102_05.sql: Tabelle erstellen (und Daten laden)
10 422
10. DB-Datenmodellierung und XSLT-Transformation
Danach registriert man ein XML Schema, welches einfach als Zeichenkette vorgegeben wird und einen eindeutigen Bezeichner in der Datenbank erhält. Es handelt sich um die schon bekannte Mitarbeiterliste mit mehreren Mitarbeitern und Vor-/Nachname sowie einer Funktionsbezeichnung. CREATE XML SCHEMA COLLECTION MaListe AS N‘
...
‘
GO -- DROP XML SCHEMA COLLECTION MaListe 102_06.sql: XML Schema registrieren (und löschen)
10. 2. 3. 2 XML Schema verwenden Um nun zu zeigen, wie man auf der einen Seite ein gespeichertes XML Schema verwendet und wie man darüber typisiertes und damit überprüfbares XML erstellt, sollen im nächsten Beispiel verschiedene Szenarien vorgeführt werden. Dazu ist zunächst wichtig, dass ein XML Schema in der Datenbank angemeldet ist. Es entspricht dem vorherigen eingetragenen Schema. Zunächst erstellt man eine T-SQL-Funktion, die als Rückgabewert XML im hochgeladenen Schema zurückliefert. Hier sieht man, wie der xml-Datentyp an der Stelle eines gewöhnlichen Datentyps verwendet wird. Er hat allerdings die Möglichkeit, in zwei verschiedenen Varianten zu erscheinen, wobei in diesem Fall die erweiterte Form zum Einsatz kommt und das XML Schema angegeben wird. Diese Funktion liefert also nur gültiges XML zurück. Dann beschafft man aus relationalen Daten der zuvor angelegten Tabellen XML-Daten im passenden Format. Dabei wird die sehr einfache Technik, XML zu erzeugen, vom MS SQL Server genutzt. Eine gewöhnliche Abfrage ergänzt man um die Klausel FOR XML, welche verschiedene Eigenschaften besitzt. In diesem Fall gibt man die beiden häufigsten an,
423
10
10. DB-Datenmodellierung und XSLT-Transformation
nämlich den Namen für das Reihen-Element und den Namen für das Wurzelelement. Die Verschachtelung bzw. der gesamte Aufbau des XML-Dokuments regeln dann die Spaltenaliasnamen, welche für jedes Element/Attribut den gesamten Pfad enthalten, den sie im Dokument bis zu den Blättern einnehmen. Handelt es sich dann um ein Attribut, so setzt man ein @-Zeichen vor den eigentlichen Attribut-Namen. Bei diesen Ausdrücken ergibt sich die Reihenfolge im resultierenden Dokument ganz einfach durch die Spaltenreihenfolge. Eine ähnliche Technik existiert auch für den umgekehrten Weg, wenn XML-Daten wieder relational zerlegt werden sollen. CREATE FUNCTION getMaListe (@funktion nvarchar(20)) RETURNS xml (MaListe) AS BEGIN
DECLARE @MaListeXML xml (MaListe); SET @MaListeXML = ( SELECT M_Anrede
FROM WHERE FOR RETURN END
AS ‚Name/@Anrede‘,
M_Vorname AS ‚Name/Vorname‘, M_Nachname AS ‚Name/Nachname‘, M_Funktion AS ‚Funktion‘ dbo.Mitarbeiter M_Funktion = @funktion XML PATH(‚Mitarbeiter‘), ROOT(‚Mitarbeiterliste‘)) @MaListeXML 102_06.sql: Funktion mit typisiertem Rückgabewert
Nachdem man nun diese Funktion erstellt hat, welche ja auch verschiedene XML-bezogene Konzepte bereits enthielt, geht es darum, sie aufzurufen und das ermittelte XML zunächst in eine Variable und dann in eine Tabelle(-nvariable) einzutragen. Dabei sieht man nun, wie einfach man eine als XML angegebene und mit einem XML Schema verbundene Variable und Spalte erstellen kann. -- Typisiertes XML erstellen DECLARE @MaListeXML xml (MaListe)
10
-- Tabelle mit XML Schema-Beschränkung DECLARE @MaListeTab table( nr int identity(1,1), data xml (MaListe)); -- Typisierte Daten abrufen und speichern
424
10. DB-Datenmodellierung und XSLT-Transformation
SET @MaListeXML = dbo.getMaListe (‚Technik‘) -- Typisiertes XML speichern
INSERT INTO @MaListeTab (data) VALUES (@MaListeXML) -- Test SELECT * FROM @MaListeTab
102_06.sql: Typisiertes XML verwenden
Im nächsten Beispiel löst man durch fehlerhaft abgerufenes XML einen Validierungsfehler aus. Alle bekannten Fehlerfunktionen können zum Einsatz kommen, um auf diesen Fehler zu reagieren bzw. ihn zunächst zu bemerken und zu analysieren. DECLARE @MaListeXML xml (MaListe); BEGIN TRY
SET @MaListeXML = ( SELECT M_Anrede AS ‚@Anrede‘, M_Vorname AS ‚Vorname‘, M_Nachname AS ‚Nachname‘, M_Funktion AS ‚Funktion‘ FROM dbo.Mitarbeiter FOR XML PATH(‚Mitarbeiter‘), ROOT(‚Mitarbeiterliste‘)) END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS Nr, ERROR_SEVERITY() AS Schwere, ERROR_STATE() AS Status, ERROR_LINE() AS Zeile, ERROR_MESSAGE() AS Meldung END CATCH 102_07.sql : Ausnahmebehandlung für ungültiges XML
Man erhält die verschiedenen ermittelten Fehlerwerte zurück, weil ja die Hierarchie-Ebene, die vom Element Name aufgespannt wird, fehlt. Dabei erscheint im Ergebnis nur der erste Fehler und nicht etwa eine Liste mit allen möglichen Fehlern. In einigen Fällen ist dies ärgerlich oder wünschenswert, aber es entspricht dem üblichen Verhalten von Prozessoren,
10 425
10. DB-Datenmodellierung und XSLT-Transformation
dass abhängige Fehler oder Folgefehler nicht auch noch aufgelistet werden, sondern die Verarbeitung beim ersten Fehler unterbrochen und eine Fehlermeldung ausgegeben wird. Nr
Schwere
Status
Zeile
Meldung
------ -------- ------- ------ ---------------------------6905 16 3 3 XML-Überprüfung: Das ‚Anrede‘-At tribut ist in diesem Kontext nicht zulässig. Ort: /*:Mitarbeiterliste[1]/*:Mitarbeiter[1]/@*:Anrede.
10. 2. 3. 3 Data Dictionary-Sichten In den beiden Sichten sys.xml _ schema _ collections und sys.xml _ schema _ namespaces kann man sich zum einen über die gespeicherten XML Schema-Angaben und zum anderen über die gespeicherten Namensräume informieren. Während die erste Sicht tatsächlich das EmpList-Schema findet, liefert die zweite Sicht Informationen zu dem im XML Schema gespeicherten Namensraum. -- Welche XML Schema sind in der DB? SELECT * FROM sys.xml_schema_collections WHERE Name = ‚MaListe‘ -- Welche Namensräume sind in der DB? SELECT * FROM sys.xml_schema_namespaces
WHERE Name = ‚http://www.ruhrfon.biz/MaListe‘ 102_08.sql: Data Dictionary abfragen
Der MS SQL Server bietet insbesondere sehr anspruchsvolle Möglichkeiten, XML-basierte Web Services auf Basis von Prozeduren und Funktionen zu erstellen. Oracle hat eine ähnliche Technik, die allerdings wohl erst ab Version 12 die Funktionalität vom MS SQL Server erreicht.
10
Unabhängig von der Perspektive, XML Schema auch in Datenbanken zu verwenden, ist die Kombination aus XML und relationaler Datenbank eine echte Erweiterung des Werkzeugkastens für Import-/Export-Szenarien oder auch die XML-basierte Anwendungsentwicklung. Datenbanken wie die beiden genannten und auch IBM DB2 bieten Validierung, Erstellung und Verarbeitung (Filterung, Transformation) direkt über die jeweilige SQL-Er-
426
10. DB-Datenmodellierung und XSLT-Transformation
weiterung oder über interne Programmierung mit anderen Sprachen. Es lohnt sich, sich für die verwendete Datenbank mit dieser Thematik zu beschäftigen.
10 427
XML Schema und OOP
11. XML Schema und OOP
11. XML Schema und OOP XML Schema ist ein Standard für die Modellierung von Datenformaten mit der Benennung von Feldern (aufgeteilt in Elemente und Attribute) und ihren Eigenschaften wie ihr zulässiger Inhalt (Datentyp ihres Inhalts oder Unter-Feld-Struktur sowie Schlüssel und Fremdschlüssel), Reihenfolgen- und Hierarchiebeziehungen. Bei der Modellierung stehen eindeutig der Aspekt des Datenformats und die Strukturierung von Dateien oder Nachrichten im Vordergrund, nicht aber bspw. der Aspekt der reinen Datenmodellierung (Aufteilung in Ober- und Unterklassen und Zuordnung von möglicherweise ebenfalls hierarchisierten Eigenschaften) oder die Abbildung von Beziehungen zwischen Daten. Ein wenig ist dies mit verschiedenen Techniken von XML Schema grundsätzlich möglich, aber es gibt hierzu weitere und besser geeignete Techniken wie bspw. die objektorientierte Modellierung mit der UML (Unified Modelling Language) oder OWL (Web Ontology Language). Nichtsdestoweniger lässt sich eine interessante und nützliche Beziehung zwischen einer objektorientierten Datenabbildung und XML Schema herstellen, die mit relativ geringem Aufwand erfolgreich genutzt werden kann. In diesem Kapitel möchten wir Ihnen die Beziehung zwischen der Abbildung von Daten in einer objektorientierten Lösung und in XML Schema sowie die leichte Umwandlung von XML-Daten in Objekte und wieder zurück in Java und .NET zeigen.
11. 1. XML Schema und Objektorientierung XML Schema bietet mit der Technik der Ableitung durch Erweiterung/Einschränkung von globalen komplexen Typen, der Redefinition sowie der Element-Ersetzungsgruppe objektorientierte Techniken für die Modellierung und Beschreibung von Datenformaten an. Diese Ähnlichkeiten sind interessant zu diskutieren und zu betrachten, da ja die Definition einer Java-/.NET-Klasse sich syntaktisch völlig anders darstellt als die Erstellung einer XML Schema-Datei. Doch solche Technologie-Vergleiche sind in diesem Kapitel nicht das Thema. Es geht vielmehr darum, wie eine Abbildung der gleichen oder sehr ähnlichen Daten erfolgreich sowohl in XML (modelliert über XML Schema) und in Java/.NET (modelliert über die Klassen) gelingen kann und welche Technologien beide Sprachen dafür bereitstellen.
429
11
11. XML Schema und OOP
11. 1. 1. Prinzip Bei objektorientierter Software gibt es Szenarien, in denen komplexe Objektstrukturen nach und nach durch den Benutzer über Formulare und Datenbearbeitung oder über Datenzugriffe, Berechnungen und die Anwendungslogik aufgebaut werden. Man kann sich bspw. vorstellen, wie über mehrere hintereinander aufgerufene Formulare bei einem Buchungs- und Bestellvorgang Daten wie die ausgewählten Produkte, Versandoptionen und schließlich Rechnungs- und Versandadresse erfasst oder bearbeitet werden. Sollen diese dann einer anderen Anwendung bereitgestellt werden, benötigt man ein Nachrichtenformat, in dem die Objektstruktur als Text-Repräsentation abgebildet wird. Diese Repräsentation entspricht der intern in der Software verwendeten Datenstruktur, sodass es sich lohnt, sie möglichst ähnlich zu modellieren, damit eine leichte Übertragung möglich ist und man selbst aus Sicht des Modellierers oder Entwicklers bei der Entwicklungs- und Planungsarbeit ein einheitliches Modell vor sich sieht und nicht etwa zwischen verschiedenen Darstellungen, Bezeichnungen und Strukturen wechseln muss. In folgenden Situationen kann eine sehr enge und ähnliche Abbildung von Daten Sinn machen: ●●
Die gleichen Daten sollen in mehreren Anwendungen genutzt werden und werden über XML-/Text-Nachrichten (typischerweise Web Services) ausgetauscht und nicht durch Zugriff auf die gleiche Datenbank.
●●
Eine Software soll fähig sein, offline und online zu arbeiten, sodass online zu speichernde Daten möglichst leicht zu serialisieren sind, um sie dann wieder in Objekte einzulesen und sie dann direkt aus der serialisierten Darstellung an die zentrale Datenbank zu senden.
●●
Eine Software soll ein eigenes Dateiformat besitzen, welches man möglichst einfach aus Objektzuständen erstellen möchte.
Für diese Anforderungen lässt sich leicht eine XML-Struktur denken. Da die Daten der Anwendung gespeichert und wieder eingelesen werden sollen, liegt es auf der Hand, dass die Art der Daten sowohl in der Software wie auch im Datei-/Exportformat sehr ähnlich sind. Daher lohnt es sich, auch die Modellierung von beiden Welten aufeinander abzustimmen bzw. gibt es nur wenige Gründe, Felder und Strukturen extra anders zu benennen oder Daten völlig umzustrukturieren. Dies würde man eher machen, wenn man bspw. auf der Grundlage eines nicht gelungenen Datenmodells ein besser überlegtes und geplantes Modell erstellen möchte und daher eine solche Umstrukturierung vornehmen würde. Es lässt
430
11
11. XML Schema und OOP
sich lediglich noch annehmen, dass insbesondere beim Ursprung der Daten noch mehr interne Daten erhoben werden, deren Export keinen Sinn ergibt, und dass natürlich Verarbeitungslogik existiert, die keinen Zustand darstellt und auch nicht exportiert werden kann. Wir gehen also davon aus, dass eine Objektstruktur möglichst ähnlich als Export-Daten bereitgestellt werden muss. Darüber hinaus gehen wir auch davon aus, dass das einzige sinnvolle Vorgehen darin besteht, XML zu verwenden und diese Daten mit XML Schema zu definieren. Möglicherweise sind auch noch relationale Strukturen in einer Datenbank zu berücksichtigen. In diesem typischen Szenario besteht dann unser Vorgehen darin, die Daten in Software, Datenbank und Export möglichst einheitlich mit XML Schema zu beschreiben, um so ein Daten-Element leicht in den verschiedenen Teilen der Gesamt-Architektur zu identifizieren. In der Abbildung hat man über eine XML Schema-Darstellung eine weitere Ebene eingefügt, welche eine Hierarchie in XML in Klassen mit Eigenschaften zerlegt. Das Vorgehen ist hierbei recht simpel: ●●
Jede Hierarchie-Ebene bzw. jeder Teilbaum steht für eine Klasse.
●●
Ein Element, das einen Textknoten enthält, und ein Attribut betrachtet man als Eigenschaften einer Klasse. Es ist lediglich bei der Übertragung von Daten festzuhalten, welche Eigenschaften nun Elemente und welche Attribute sind.
●●
Ein Element, das selbst wieder Kind-Elemente hat, stellt eine Eigenschaft einer Klasse dar, die ein Objekt enthält.
●●
Eine Gruppe von Geschwister-Elementen stellt die Eigenschaften einer Klasse dar. Dabei unterscheidet man zwischen primitiv typisierten und über eine Klasse typisierte Eigenschaften.
●●
Kann ein Element mehrfach im Instanzdokument erscheinen, ist es als Collection oder Array zu betrachten.
Das Beispiel setzt die schon an anderer Stelle verwendete Erfolgsübersicht ein. Für die Abbildung der gesamten Struktur benötigt man eine Klasse, die eine Eigenschaft besitzt, welche als Collection mehrere Erfolge speichern kann. Jeder Erfolg ist wiederum eine Klasse mit insgesamt vier Eigenschaften, von denen zwei in XML als Attribut und zwei als Element modelliert sind. Während die beiden Attribut-Eigenschaften primitiv typisiert sind, bilden die beiden Element-Eigenschaften zwei Teilbäume in XML ab. Diese modelliert man in der
431
11
11. XML Schema und OOP
objektorientierten Variante als zwei Klassen, von denen jeweils eine Instanz in den Eigenschaften referenziert wird. Diese beiden Klassen besitzen dann einmal zwei und einmal drei primitiv typisierte Eigenschaften. Dieses Beispiel bietet keine großen Anknüpfungspunkte für Diskussionen, wie man diese oder jene Struktur gut in Java oder .NET abbilden könnte. Stattdessen kann man sich leicht vorstellen, wie die XML-Daten fast 1:1 als Objektstruktur dargestellt werden können. Ein typisches Beispiel, bei dem nicht nur eine statische Struktur, sondern auch Verarbeitungslogik einzusetzen wäre, ist der Einsatz von Schlüsseln und Fremdschlüsseln. Der Prüfmechanismus ist in XML Schema deklarativ, während die Logik in Java/.NET tatsächlich implementiert werden müsste.
Abbildung 11.1: Zuordnung zwischen XML-Elementen/-Strukturen und Klassen-Elementen/-Strukturen
Als Zusammenfassung dieses Abschnitts kann man nun noch beide Welten – die objektorientierte und die XML Schema-Welt – zusammen in eine Abbildung bringen. Sie zeigt die folgenden Aspekte: ●●
432
11
Das Datenmodell und damit die Strukturdefinitionen sind in XML Schema und in der Klassendefinition hinterlegt. Es ist nicht immer notwendig, eine 1:1-Zuordnung herzustellen, denn oft wird nur ein Teil der Daten in XML oder der Software benötigt.
11. XML Schema und OOP
●●
Die Instanzen sind dann entweder die XML-Instanzdokumente, da sie gültige Entsprechungen des XML Schema sind, oder die Objekte, da sie auf Basis der Klassen instanziiert wurden.
●●
Die Erzeugung von XML Schema-Dateien aus den Klassendefinitionen oder umgekehrt, lässt sich durch schon vorhandene Generator-Software durchführen. Ebenfalls vorhandene weitere Software nutzt Anmerkungen in den Klassen oder auch der XML SchemaDatei, um die Instanzen ebenfalls bei Bedarf zu überführen.
Abbildung 11.2: Vergleich XML Schema und Klassen sowie deren Instanzen
11. 1. 2. Funktionsweise Der grundsätzliche Nutzen der Vorgehensweise ist sicherlich deutlich geworden. Es ist lediglich unklar, welche Arbeitsschritte und welcher Aufwand bei der Entwicklung der entsprechenden Import-/Export-Software oder Zuordnungs- und Übertragungssoftware not-
433
11
11. XML Schema und OOP
wendig sind. Man kann sich sicherlich leicht vorstellen, dass man bei der Planung gleichzeitig die XML Schema-Datei und die entstehenden bzw. notwendigen Klassen berücksichtigt und wie man einfach beides parallel und aufeinander abgestimmt entwickelt. Dies sind allerdings nur die einfachen statischen Strukturen. Man benötigt ja noch eine weitere Komponente, mit der aus XML-Daten die Objekte und aus den Objekten die XML-Daten erzeugt werden. Hier ahnt man vielleicht, dass man einen generischen Algorithmus benötigt, der unter Rückgriff auf die XML Schema-Datei oder weitere Daten die passenden Zuordnungen vornimmt. Doch wie dies genau gelingen soll, liegt etwas im Nebel und scheint schwierig so planbar, dass man die Software später gut erweitern oder auch wiederverwenden kann. Stattdessen ist es so, dass man in Java und .NET auf eine voll entwickelte Bibliothek zurückgreifen kann und nicht gezwungen ist, den gesamten Mechanismus selbst zu entwickeln. Wenn die Bindung zwischen XML Schema und den Klassen eingerichtet ist, verringert sich der Arbeitsaufwand der Instanzdaten-Übertragung auf wenige Quelltextzeilen. Die Bindung selbst wiederum lässt sich wiederum mit fertigen Software-Komponenten bewerkstelligen und erfordert normalerweise nur Anmerkungen in der XML Schema-Datei (wenn die Klassen generiert werden sollen) oder in der Klasse (wenn die XML Schema-Datei generiert werden soll). Diese Anmerkungen werden dann auch bei der Instanzdatenumwandlung ausgelesen.
Abbildung 11.3: Generierung und (Un)Marshalling
434
11
11. XML Schema und OOP
Es gibt also in beiden Technologien ein Kommandozeilentool, mit dem die XML Schemaund Klassen-Dateien generiert werden können. Und ebenfalls gibt es in beiden Technologien Klassen, welche für die Serialisierung und Deserialisierung genutzt werden können. Allerdings heißt das Vorgehen nicht mehr (De)Serialisierung, sondern (Un)Marshalling. Marshalling meint dabei die Umwandlung von Objekten in XML, während Unmarshalling die Umwandlung von XML in Objekte meint. Die zweite Abbildung dieses Abschnitts fasst dann die verschiedenen Konzepte noch einmal zusammen. ●●
Die Klassen werden an das XML Schema gebunden und umgekehrt. Dafür gibt es Kommandozeilentools zur Generierung der fehlenden Dateien.
●●
Die XML-Instanzdaten folgen ihrem XML Schema.
●●
Die Objekte folgenden ihren Klassendefinitionen.
●●
Zwischen den Instanzdaten in Objekten und XML findet eine Umwandlung statt – Marshalling und Unmarshalling genannt. Dafür gibt es Framework-Klassen zur Umwandlung der Instanzdaten unter Rückgriff auf die Bindungsinformationen.
Abbildung 11.4: Architektur-Überblick über XML Schema-Klassen-Bindung
435
11
11. XML Schema und OOP
11. 1. 3. Erweiterung auf Datenbanken Der Zusammenhang zwischen den verschiedenen Konzepten (XML Schema, Objektorientierung, relationale Modellierung), die auch wieder unter verschiedenen Perspektiven (Betonung der Gemeinsamkeiten oder der Unterschiede von Datenerfordernissen, Berücksichtigung von vorgegebenen Datenschnittstellen) betrachtet werden können, lässt sich noch sehr viel ausführlicher beschreiben, wenn man alternative Design-Möglichkeiten und Sonderfälle, die sich ja immer finden lassen, hinzunimmt. Projektspezifische Fragestellungen können dann natürlich noch einmal weitere Kriterien oder andere Gewichtungen erfordern. Daher sind die bisherigen Ausführungen oberflächlich und können nur die wesentlichen Prinzipien darstellen, ohne Vor- und Nachteile von Varianten und Vorgehensweisen zu diskutieren. Trotz dieser Kürze – es sollen ja auch noch konkrete Beispiele in Java und .NET - soll eine häufige Erweiterung und damit ein zusätzlicher Aspekt beleuchtet werden: die Integration einer Datenbank und damit der relationalen Modellierung. Es ist leicht vorstellbar, dass viele Softwarelösungen, die XML-Daten und damit auch Import/Export oder Offline-/OnlineKapazitäten erforderlich machen, auch eine zentrale Server-Datenbank beinhalten. Diese Datenbank kann dann wiederum eine eigene Datenbank sein, während die Import-/ExportDaten fremde Datenbanken und fremde Server betreffen könnten und damit noch die Aspekte Datenübertragung, Sicherheit oder Plattformunabhängigkeit mit ins Spiel bringen. Wie man sieht, lässt sich das Spiel der Komplexitätserweiterung ins Unendliche fortsetzen. Daher sollen nur die folgenden zentralen Gedanken zum Thema Datenbank-Integration noch präsentiert werden: Oft wird es so sein, dass für ein Import-/Export-Szenario die Datenstrukturen auch in einer relationalen Datenbank wiederzufinden sind. Möglicherweise sind – wie auch in der Software – noch weitere zusätzliche Datenelemente vorhanden, doch man kann einen gemeinsamen Datenbestand als Schnittmenge der verschiedenen Einheiten Software, Datenbank und Import-/Export-Schnittstelle (nach außen oder intern) ausmachen. Dann lohnt es sich natürlich zur Reduktion der Anwendungs- und Entwicklungskomplexität, die Daten, die zwischen diesen verschiedenen Einheiten transportiert werden, einheitlich zu modellieren. Damit ist nicht gemeint, dass bspw. aus der Datenbank die benötigten Daten exportiert werden sollen oder die Datenbank nur die benötigten Daten erhält. Dies ist trivial und ohnehin erforderlich, um überhaupt eine sinnvolle Schnittstelle zu konstruieren. Es geht vielmehr darum, dass nicht die Software zunächst mit einer SQL-Abfrage die Daten aus der Datenbank abruft und dann gemäß der Import-/Export-Schnittstelle passend
436
11
11. XML Schema und OOP
zusammensetzt, sondern dass bereits die Datendefinition in der Datenbank direkt Berücksichtigung findet. Man verlagert also einen Teil der Anwendungslogik. Dies gelingt, wenn man bei Datenbank-Prozeduren auf die XML Schema-Datei zurückgreift und die Prozeduren nicht nur traditionelle Ergebnismengen liefern, sondern sofort XML-Daten im passenden Format. Mit Datenbanken von Oracle, Microsoft und IBM hat man dafür geeignete SQL-Erweiterungen, um XML-Daten zu liefern, zu validieren und auch umzuwandeln. Eine solche XML-fähige Datenbank erlaubt es, ein XML Schema zu laden und als eigene Ressource wie einen sehr umfassenden Datentyp für Spalten, Variablen, Parameter oder Rückgabewerte zu nutzen. Dies bedeutet, dass Prozeduren oder Funktionen nicht nur im Export-Fall die passenden XML-Daten liefern, sondern sie auch akzeptieren und intern weiterverarbeiten können. Selbstverständlich ist es nicht immer zweckmäßig oder gewünscht, Prozeduren in der Datenbank zu entwickeln, weil bspw. die Software sowohl für Oracle wie auch für den MS SQL Server nutzbar sein soll. Doch auch in einem solchen Fall sollte das Software-Modul, welches die DB-Daten umwandelt, unter Rückgriff auf die XML Schema-Datei die passenden Daten liefern oder erstellen und diese Logik zentralisieren. Weil die Software selbst wiederum (Un)Marshalling einsetzt, verschwimmen dadurch die Grenzen zwischen der intern genutzten Objektstruktur und den gelieferten Import-Daten oder den extern benötigten Export-Daten. An allen Stellen der Architektur, die sich mit den hin und her transferierten Daten abmühen, greift man auf die gleiche zentrale Modellierung zurück. Im schönsten Fall hat man sogar ein Benennungsschema für die Datenelemente, welches durchgängig von Datenbank über Software bis zu den Dateien genutzt werden kann, und so die Komplexität bei der Anwendungsentwicklung reduziert. Wie Sie vielleicht schon erahnen, gelangt man zum Thema „einheitliches Unternehmensdatenmodell“, das nicht nur für die hier immer erwähnte Software, sondern für alle im Unternehmen eingesetzten Software-Lösungen zum Einsatz kommt. Dies bleibt in den meisten Fällen aus Gründen, die hier zu weit führen, eine Utopie, oder wird trotz Existenz einer zentralen Datenbeschreibung auch häufig bei Insel-Lösungen durchbrochen. Doch man schafft sich über das beschriebene und nun um Datenbanken erweiterte Vorgehen einige lokale stabile Datenstrukturen. Die Abbildung stellt zwei verschiedene Vorgehensweisen dar: ●●
Setzt man den traditionellen Weg über SQL und Ergebnismengen ein, so ruft man Daten in einem nicht weiter typisierten Format ab und formt aus diesen dann die benötigten Objektstrukturen. Sollen Daten wieder zur Datenbank geschickt werden, muss
437
11
11. XML Schema und OOP
man sie in einzelne SQL-Anweisungen umwandeln, die dann die relationalen Strukturen referenzieren und die entsprechenden Daten einhalten. ●●
Setzt man auf die XML Schema-Bindung, dann erhält man direkt von der Datenbank das benötigte XML, welches dann in die benötigten Objekte umgewandelt wird. Der umgekehrte Weg ist genauso einfach, denn hier wandelt man die Objektstruktur in XML um und übergibt dieses an die Datenbank, die dann die XML-Daten relational zerlegen muss.
(De)Serialisierung
XML data
Datenbank XMLSchnittstelle
Sicht
(Un)Marshalling
Tabelle 1
Tabelle 2
SQLSchnittstelle
Ergebnismenge (Objekte)
Umwandlung SQL-Befehle und Daten
Relationale Modellierung
Objekte
XMLModellierung
Gemeinsame Daten-Elemente
Abbildung 11.5: Architektur-Überblick mit zusätzlicher Datenbank
438
11
Objektorientierte Modellierung
11. XML Schema und OOP
11. 2. XML Schema-Bindung in .NET Ab .NET 2.0 besteht die Möglichkeit, aus XML Schema .NET-Klassen zu erzeugen oder aus einer Laufzeitassemblydatei (Erweiterung .exe oder .dll) XML Schema-Klassen. Dabei setzt man ein im Visual Studio-Ordner vorhandenes Kommandozeilen-Tool namens XSD.exe ein. Die Klassen werden bei der Generierung automatisch mit Annotationen versehen, welche die Zuordnung zwischen .NET und XML Schema festlegen. Durch diese Annotationen kann man das zu erstellende XML Schema aus den Klassen sowie dann auch später das (Un) Marshalling beeinflussen.
11. 2. 1. Prinzip der Klassengenerierung aus XML Schema Die klassische Vorgehensweise besteht darin, zunächst zu testen, was überhaupt passiert, wenn man eine einfache XML Schema-Datei zu Klassen umwandelt. Die einfachste XML Schema-Datei ist dabei eine, die im Matrjoschka-Design erstellt wurde. Im nachfolgenden Beispiel ersetzen die drei Punkte jeweils den Pfad zur XSD.exe-Datei, zur XML Schema-Datei und zum Ausgabeordner. C:\...\xsd.exe „C:\...\matrjoschka.xsd“ /c „/l:CS „ „/o:C:\...\CS-1“
Die wichtigsten Parameter sind in der nachfolgenden Liste enthalten: ●●
/h[elp] oder /? - Listet die Befehlsoptionen auf.
●●
/o[utputdir]:directory - Legt das Verzeichnis für Ausgabedateien fest (Standardwert:
aktuelles Verzeichnis). ●●
/c[lasses] - Generiert Klassen entsprechend dem angegebenen XML Schema.
●●
/f[ields] - Generiert Felder anstelle von Eigenschaften (Standardeinstellung).
●●
/l[anguage]:language - Gibt die Programmiersprache an (CS, Standard), VB, JS oder VJS.
●●
/n[amespace]:namespace - Legt den Laufzeitnamespace fest (Standardnamespace ist Schemas).
439
11
11. XML Schema und OOP
●●
/o[ut]: directoryName - Legt das Ausgabeverzeichnis fest (Standardverzeichnis ist der aktuelle Ordner).
Weitere Informationen finden Sie unter http://msdn.microsoft.com/de-de/library/ x6c1kb0s(v=vs.80).aspx. Zu diesem Konsolenprogramm gibt es von der Firma Soft3K ein nützliches einfaches GUIWerkzeug (http://www.soft3k.com/Visual-XSD-p8651.htm). Neben den verschiedenen Optionen, die man einfach markieren und ggf. mit Werten versehen kann, ruft es das XSD.exeProgramm auf und zeigt auch den eingegebenen Konsolenaufruf sowie mögliche Fehler an.
Abbildung 11.6: Verwendung von VisualXSD
Die sehr einfach aufgebaute Datei matrjoschka.xsd führt zu Klassen, die man ernsthaft nicht weiter verwenden kann. Um die verschachtelte Klassenhierarchie abzubilden, sind mehrere Klassen notwendig. Die Namen setzen sich bei einem Matrjoschka-Design einfach aus den in der XML-Hierarchie aufeinander folgenden Element-Namen zusammen.
440
11
11. XML Schema und OOP
Dadurch werden diese Namen sehr unhandlich. Man kann allerdings dennoch mit einer solch einfachen Datei das allgemeine Vorgehen testen. Die Abbildung zeigt das XML Schema-Diagramm und in grauen Kästchen die Namen der erzeugten Klassen.
Abbildung 11.7: Generierte Klassen aus Matrjoschka-Design (matrjoschka.cs)
Die generierten Klassen enthalten den angekündigten Aufbau. Dies bedeutet, dass aus Elementen und Attributen jeweils Eigenschaften der Klassen werden. Attribute und einfach typisierte Elemente werden mit einem passenden Datentyp erzeugt. Enthalten Elemente dagegen weitere Kind-Elemente oder Attribute, so wird eine neue Klasse generiert mit den jeweiligen Elementen oder Attributen als Eigenschaften. Da im Beispiel ein Element mehrfach auftritt, wird auch ein Array erzeugt, in dem dann in der Eigenschaft der Klasse mehrere Objekte des passenden Typs enthalten sein können. Die Abbildung zeigt die um die so genannten Annotationen und weitere generierte Kommentare bereinigten Klassendefinitionen. Man erkennt leicht den Aufbau aus der XML Schema-Datei wieder.
441
11
11. XML Schema und OOP
Abbildung 11.8: Generierte Klassen (matrjoschka.cs)
11. 2. 2. XML Schema-Bindung Das vorherige Beispiel zeigte, dass zwar auch aus einer solch einfachen XML Schema-Datei ein Klassensystem erzeugt wird, doch die Klassennamen sind nicht für die weitere Verwendung geeignet. Man möchte also wenigstens die Klassenstruktur etwas genauer vorgeben und vielleicht sogar die Namen in XML verschieden von denjenigen in den Klassen und Eigenschaften vorgeben. In der XML Schema-Datei komplexeTypen.xsd ist nun die typische Form enthalten, die bei der Generierung von Klassen zu Grunde gelegt wird: Jeweils ein neuer globaler komplexer Typ bildet eine Hierarchie-Ebene in der XML Schema-Datei. Die Namen dieser Typen legen dann die zu erzeugenden Klassennamen fest, sofern keine anderen Einstellungen getroffen
442
11
11. XML Schema und OOP
wurden. Des Weiteren ist in der Datei eine Vererbungshierarchie zwischen den Typen UmsatzTyp und GesamtTyp vorhanden, bei der in GesamtTyp noch ein weiteres Element angehängt wird. Diese Vererbung wird ebenfalls in eine Klassen-Hierarchie übertragen.
{
{}
}
class
{
}
{
}
{
}
schema
Abbildung 11.9: Generierte Klassen aus globalen komplexen Typen (komplexeTypen.cs)
Die Klassen haben nun die gewünschten Namen und besitzen auch die entsprechende Vererbungshierarchie. Die Eigenschaften referenzieren nun natürlich die neu gebildeten Klassen, sind aber ansonsten ähnlich wie zuvor aufgebaut.
443
11
11. XML Schema und OOP
public partial class Erfolguebersicht { private ErfolgTyp[] erfolgField;
}
public ErfolgTyp[] Erfolg { get { return this.erfolgField; } set { this erfolgField = value; } }
public partial class ErfolgTyp {
public partial class GesamtTyp : UmsatzTyp {
private GesamtTyp gesamtField; private UmsatzTyp proKopfField; private string stadtField; private string monatField; public GesamtTyp Gesamt { get { return this gesamtField; } set { this gesamtField = value; } } public UmsatzTyp ProKopf { get { return this proKopfField; } set { this.proKopfField = value; } }
}
private int kundenField;
}
public int Kunden { get { return this kundenField; } set { this.kundenField = value; } }
public partial class UmsatzTyp { private decimal umsatzField; private decimal anrufeField; public decimal Umsatz { get { return this umsatzField; } set { this.umsatzField = value; } }
public string Stadt { get { return this.stadtField; } set { this.stadtField = value; } } public string Monat { get { return this.monatField; } set { this.monatField = value; } } }
public decimal Anrufe { get { return this anrufeField; } set { this.anrufeField = value; } }
Abbildung 11.10: Generierte Klassen (komplexeTypen.cs)
11. 2. 3. Mapping und Serialisierung beeinflussen Manchmal ist bereits eine Klassenstruktur vorhanden, die nach XML Schema überführt werden soll, um aus den daraus resultierenden Objektstrukturen vorher festgelegte XMLInstanzdaten zu gestalten. In diesem Fall muss man sich mit den verschiedenen Attributen beschäftigen, die man für Klassen und Eigenschaften/Felder verwenden kann, um die Serialisierung vorzugeben. Sie kommen auch zum Einsatz, wenn man Web Service-Nachrichten strukturieren möchte. Diese Attribute waren auch in den vorab generierten Klassen enthalten, wurden aber nicht in die Abbildungen übernommen oder weiter diskutiert, da ihre Einstellungen und Syntax-Varianten doch recht umfangreich sind, obwohl ihre Anzahl wiederum sehr überschaubar ist.
444
11
11. XML Schema und OOP
Die verschiedenen Attribute sind für unterschiedliche Klassenmember oder sogar eine ganze Klasse gültig. Für die meisten stehen überladene Versionen bereit, mit denen man mehr oder weniger Eigenschaften setzen kann. Das einfachste Beispiel ist sicherlich XmlElement. Eine überladene Version erwartet als Zeichenkette nur den Namen, eine andere lässt Namen, Datentyp und weitere Eigenschaften in der Form name = wert zu. In den nachfolgenden Beispielen werden alternative Verwendungen gezeigt. Aus Platzgründen können allerdings nicht alle Varianten diskutiert werden. Für dieses Kapitel soll es genügen, sie beispielhaft einzuführen. Im nachfolgenden Beispiel legt man Einstellungen für die Klasse Erfolguebersicht fest. Da sie die oberste Klasse der Klassenstruktur darstellt, kann man mit XmlRoot festlegen, dass ein Zielnamensraum generiert werden soll und wie Name und globaler komplexer Typ für diese Klasse und das oberste Element sein sollen. Alternativ – so war es im XML Schema in der Datei komplexeTypen.xsd – kann man auch einen so genannten anonymen Typ verwenden. Dann ist der komplexe Typ nur lokal und hat also keinen Namen (anonym). Die folgenden Eigenschaften sind für die verwendeten Attribute besonders wichtig: ●●
XmlRoot legt das XML-Wurzel-Element fest.
ElementName - Explizit vorgegebener Name des XML-Elements oder automatisch aus der Eigenschaft abgerufen. DataType - Explizit vorgegebener XML Schema-Datentyp oder automatisch aus .NET-Datentyp abgeleitet/angepasst. IsNullable - Legt fest, dass ein leeres Element mit xsi:nil-Attribut generiert wird, wenn kein Wert im Objekt gespeichert ist. Namespace - XML-Namespace des XML-Wurzel-Elements. ●●
XmlType legt Eigenschaften für Klassen, Strukturen, Enumerationen oder Schnittstel-
len fest und hat selbst folgende Eigenschaften:
AnonymousType - Legt fest, ob ein globaler komplexer Typ erstellt werden soll oder ob er nur lokal sein soll.
445
11
11. XML Schema und OOP
IncludeInSchema - Legt fest, ob der Typ in das XML Schema aufgenommen werden soll. Normalerweise ist dies bei verbundenen Strukturen der Fall, damit die Deklarationen gültig bleiben. Namespace - Legt den Namensraum des Typs fest. TypeName - Legt den Namen des Typs fest. Normalerweise ist dies der Name von Klasse, Schnittstelle etc. using System.Xml.Serialization; [XmlRoot(Namespace = “http://www.ruhrfon.biz”, ElementName = “Uebersicht”)] // Alternative: anonymer Typ //[XmlType(AnonymousType=true)] [XmlType(“UebersichtTyp”)] public partial class Erfolguebersicht { private ErfolgTyp[] erfolg;
}
[XmlElement(ElementName = “Erfolg”, IsNullable = false)] public ErfolgTyp[] Erfolg { get; set; } komplexeTypenAnnotationen.cs: Wurzelelement und seine Kinder
Aus öffentlichen Eigenschaften werden normalerweise automatisch XML-Elemente generiert. Möchte man lieber Attribute, den Namen oder automatisch gewählten Datentyp ändern sowie natürlich Eigenschaften nicht serialisieren, gibt man dies mit den Attributen XmlElement, XmlAttribute oder XmlIgnore an. Die folgenden Eigenschaften dieser Attribute sind besonders wichtig: ●●
XmlElement legt fest, wie das Klassenmember aus Element generiert werden soll.
ElementName - Explizit vorgegebener Name des XML-Elements oder automatisch aus der Eigenschaft abgerufen.
446
11
11. XML Schema und OOP
DataType - Explizit vorgegebener XML Schema-Datentyp oder automatisch aus .NET-Datentyp abgeleitet/angepasst. Type - Explizit vorgegebener komplexer Typ des XML-Elements oder aus .NET-Objekttyp abgerufen. IsNullable - Legt fest, dass ein leeres Element mit xsi:nil-Attribut generiert wird, wenn kein Wert im Objekt gespeichert ist. Form - Legt fest, ob das XML-Element qualifiziert (mit Namensraum-Präfix) sein muss oder nicht. Namespace - XML-Namespace des XML-Elements. Order - Platz in der Ordnungsreihenfolge in XML. ●●
XmlAttribute legt fest, wie das Klassenmember aus Attribut generiert werden soll.
AttributeName - Explizit vorgegebener Namen des XML-Attributs oder automatisch aus der Eigenschaft abgerufen. DataType - Explizit vorgegebener XML Schema-Datentyp oder automatisch aus .NET-Datentyp abgeleitet/angepasst. Namespace -XML-Namespace des XML-Attributs. public partial class ErfolgTyp { private private private private private
GesamtTyp gesamt; UmsatzTyp proKopf; string stadt; string monat; string region;
// Berücksichtigung als Element mit Umbenennung [XmlElement(ElementName = “Total”, IsNullable = true)] public GesamtTyp Gesamt { get; set; } // Berücksichtigung als Element gleichen Namens [XmlElement(IsNullable = true)]
447
11
11. XML Schema und OOP
public UmsatzTyp ProKopf { get; // Unberücksichtigt lassen [XmlIgnore]
public string Region { get;
set; }
set; }
// Berücksichtigung als Attribut und Namensänderung //[XmlAttribute(“Ort”)]
[XmlAttribute(AttributeName = “Ort”, DataType=”string”)] public string Stadt
{ get;
set; }
// Berücksichtigung als Attribut gleichen Namens [XmlAttribute()] }
public string Monat { get;
set; }
komplexeTypenAnnotationen.cs: Elemente und Attribute definieren
Da ja grundsätzlich über die Standard-Serialisierung auch schon ein XML Schema bzw. aus nicht weiter annotierten Objektstrukturen auch XML-Daten erzeugt werden können, gibt es dafür geeignete Vorgabewerte. Diese kann man teilweise im nächsten Beispiel sehen. Da GesamtTyp von UmsatzTyp erbt und auch aus der Klasse Erfolguebersicht aufgerufen wird, muss er in das XML Schema aufgenommen werden, damit die Deklarationen alle gültig bleiben. Als Name für den entstehenden globalen komplexen Typ wird dann der Klassenname verwendet. Die Vererbung wird ebenfalls über Ableitung durch Erweiterung nachgebildet. Des Weiteren kann man noch die Kurzformen für die Umbenennung von Elementen/Attributen sowie die explizite Berücksichtigung von verbundenen .NET-Typen (Klasse UmsatzTyp) über das XmlInclude-Attribut sehen. // Keine expliziter Hinweis auf Verwendung public partial class GesamtTyp : UmsatzTyp { private int kunden; // Berücksichtigung als Element und Umbenennung [XmlElement(“Kundenzahl”)] public int Kunden { get; set;
448
11
11. XML Schema und OOP
}
}
// Expliziter Hinweis auf Verwendung [XmlInclude(typeof(UmsatzTyp))] public partial class UmsatzTyp { private decimal umsatz; private decimal anrufe; // Explizite Berücksichtigung als Element [XmlElement(“Umsatz”)] public decimal Umsatz { }
get; set;
// Implizite Berücksichtigung als Element
}
public decimal Anrufe { get; set; }
komplexeTypenAnnotationen.cs: Weitere Angaben und Syntax-Varianten
Man setzt dann ebenfalls das XSD.exe-Tool ein, um aus der DLL, welche aus dem Projekt AttributTest entstanden ist, die XML Schema-Datei zu erzeugen. Da in den meisten DLLs wohl mehr als nur eine Klasse zu finden sein dürfte, muss man angeben, bei welcher Klasse die Generierung beginnen soll. In diesem Fall handelt es sich um die oberste Klasse des Baums Erfolguebersicht. Nachfolgend finden Sie den verwendeten Kommandozeilenaufruf, wobei die drei Punkte wieder die Dateipfade abkürzen. Die Assembly bzw. das Visual Studio-Projekt finden Sie im Ordner AttributTest. C:\...\xsd.exe „C:\...\AttributTest.dll“ „/o:C:\...\AttributTest“ „/t:Erfolguebersicht“
Im Wesentlichen entspricht das generierte XML Schema demjenigen, mit dem wir zu Anfang begonnen haben.
449
11
11. XML Schema und OOP
Abbildung 11.11: Generiertes XML Schema
Um die verschiedenen Einstellungsmöglichkeiten zu zeigen, welche bei den Serialisierungsattributen denkbar sind, gibt es aber dennoch einige Unterschiede: Der Zielnamensraum ist im XML Schema enthalten; jedoch wurde automatisch der Standardpräfix tns erzeugt und bei der Verwendung von globalen Komponenten sowie auch bei den lokalen Komponenten verwendet, obwohl dies nicht unbedingt notwendig ist. Einige Elemente haben einen anderen Namen als zuvor, da sie in der Klasse anders vorgegeben wurden. Das Wurzelelement besitzt keinen anonymen komplexen Typ, sondern es gibt nun einen neuen globalen komplexen Typ namens UebersichtsTyp. Die Elemente können schließlich leer (nillable) sein.
450
11
11. XML Schema und OOP
...
Generiert.xsd: Ausschnitt aus der generierten XML Schema-Datei
Weitere Informationen zu den verschiedenen Attributen und ihren Eigenschaften finden Sie unter: http://msdn.microsoft.com/de-de/library/83y7df3e.aspx
11. 2. 4. Generierte Klassen erweitern In den meisten Fällen möchte man nicht nur die Objektstruktur für die reine Datenspeicherung und als objektorientierte Abbildung einer komplexen Datenstruktur nutzen, sondern auch weitere Verarbeitungslogik oder weitere Felder/Eigenschaften einfügen. Im aktuellen Fall könnte man sich vorstellen, dass man noch eine Gesamtanzahl aller Anrufe oder den gesamten Umsatz ausrechnet und als Eigenschaft anbietet. Auch die Verwaltung von mehrfach auftretenden Elementen, die in .NET als einfaches Array umgesetzt werden, bietet Erweiterungsmöglichkeiten. Das wichtigste Ziel ist dabei natürlich, dass die generierten Klassen nicht direkt in der generierten Datei geändert werden, weil ja diese Datei bei einer erneuten Generierung überschrieben wird. Diese generierten Dateien müssen also unangetastet bleiben. Das nachfolgende Beispiel zeigt daher eine einfache Lösung, um weitere Elemente über eine ErfolgHinzufuegen()-Methode hinzuzufügen und nicht etwa die Array-Verwaltung außerhalb des gesamten Klassensystems durchzuführen. Dabei erstellt man in einer zweiten Datei im gleichen Namensraum weitere Teile der ja bereits durch die Generierung als partiell erzeugten Klassen. Beim Anruf können dann beide Dateien/Definitionen als Einheit genutzt werden. namespace MarshallingTest { public partial class Erfolguebersicht {
public void ErfolgHinzufuegen(ErfolgTyp erfolg) { List erfolge = new List(); if (this.Erfolg != null) {
451
11
11. XML Schema und OOP
}
erfolge.AddRange(this.Erfolg);
erfolge.Add(erfolg);
}
}
}
this.Erfolg = erfolge.ToArray();
komplexeTypenErweitert.cs: Erweiterung der generierten Klassen
11. 2. 5. Von XML zu Objekten Nun fehlen noch zwei Beispiele, die zeigen, wie leicht man über diese gesamte Technik XML-Daten in Objekte umwandeln kann und auch wieder zurück von Objekte in XML gelangt.
11. 2. 5. 1 Marshalling Im ersten Beispiel erstellt man über die generierten Klassen eine verschachtelte Objektstruktur. Im Gegensatz zur Arbeit mit anderen XML-Bibliotheken wie bspw. mit dem DOM (Document Object Model) beschäftigt man sich im Quelltext überhaupt nicht damit, dass man später eine XML-Datei generieren will. Man kann auch den Aspekt der XML-Erstellung völlig außen vor lassen und zunächst weiter mit den Objekten arbeiten. Während man beim DOM von vornherein einen überaus langen und meist auch durch Wiederholung geprägten Quelltext erstellt, an dem man manchmal bei sehr tief verschachtelten Strukturen gar nicht mehr erkennen kann, was für eine XML-Struktur über Zeilen hinweg formuliert wird, arbeitet man nun nicht mit einer objektorientierten Dokument-Darstellung, sondern mit einer objektorientierten Daten-Darstellung. Dies bedeutet, dass man nicht als zu Grunde liegendes Datenmodell in den Kategorien „Element“, „Attribut“ oder „Textknoten“ denkt, sondern in „ProKopf“, „Gesamt“ und „Erfolg“. // Erstellung einer Erfolgsübersicht
Erfolguebersicht uebersicht = new Erfolguebersicht(); ErfolgTyp erfolg = new ErfolgTyp(); erfolg.Monat = „10.04“; erfolg.Stadt = „Essen, Ruhr“;
452
11
11. XML Schema und OOP
GesamtTyp gesamt = new GesamtTyp(); gesamt.Anrufe = 18869; gesamt.Kunden = 200;
gesamt.Umsatz = (decimal)7154.01; UmsatzTyp proKopf = new UmsatzTyp(); proKopf.Anrufe = (decimal)94.35; proKopf.Umsatz = (decimal)35.77; erfolg.Gesamt = gesamt;
erfolg.ProKopf = proKopf; //ErfolgTyp[] erfolgListe = { erfolg }; //uebersicht.Erfolg = erfolgListe;
uebersicht.ErfolgHinzufuegen(erfolg); Program.cs: Marshalling – Erstellung der Objektstruktur
Die Klasse XmlSerializer aus dem Namensraum System.Xml.Serialization bietet die notwendige Funktonalität zur Umwandlung einer Objektstruktur in XML an. Der Konstruktor ewartet die Typ-Angabe der obersten Klasse der Klassenstruktur und kann dann die Serialisierung über die Serialize()-Methode vornehmen, welche das oberste Objekt, das alle anderen enthält, ewartet. // Serialisierung XmlSerializer serializer = new XmlSerializer(typeof(Erfolguebersicht)); TextWriter writer = new StreamWriter(filename); serializer.Serialize(writer, uebersicht); writer.Close(); Program.cs: Marshalling – Tatsächliche Umwandlung in XML
11. 2. 5. 2 Unmarshalling Der umgekehrte Weg ist ebenfalls sehr einfach. Die gerade erzeugte XML-Datei wird über den nachfolgenden Vorgang wieder in eine Objektstruktur eingelesen und kann dann wie-
453
11
11. XML Schema und OOP
der über die Eigenschaften/Felder angesprochen werden. Hätte man noch weitere Methoden oder Eigenschaften in partiellen Klassen erstellt, so könnte man diese ebenfalls für die Weiterverarbeitung nutzen. Ebenfalls ist wieder die XmlSerializer-Klasse zu instanziieren. Sie erwartet erneut die Typ-Angabe des obersten Elements der zu erzeugenden Objektstruktur und führt den Umwandlungsvorgang dann mit der Deserialize()-Methode durch. // Deserialisierung XmlSerializer serializer =
new XmlSerializer(typeof(Erfolguebersicht)); FileStream fs = new FileStream(filename, FileMode.Open); Erfolguebersicht uebersicht;
uebersicht = (Erfolguebersicht)serializer.Deserialize(fs); // Ausgabe und Weiterverwendung Console.WriteLine(„Anrufe gesamt: „
+ uebersicht.Erfolg[0].Gesamt.Anrufe); Console.WriteLine(„Anrufe pro Kopf: „ + uebersicht.Erfolg[0].ProKopf.Anrufe); Program.cs: Unmarshalling
11. 2. 5. 3 Standard-XML-Serialisierung Man kann die XmlSerializer-Klasse und damit die gesamte Technik der XML-Serialisierung auch verwenden, wenn man sich nicht XML Schema beschäftigt hat und/oder in dem zu serialisierenden Klassensystem auch keine Attribute zur Art und Weise des XML-Aufbaus vorhanden sind. In diesem Fall erhält man eine Standard-Lösung, die zwar irgendwie unserem XML Schema entsprechen würde, aber natürlich nicht genau unseren Regeln folgt. Anstatt also diese Standard-XML-Serialisierung zu verwenden, greift der XmlSerializer auf die in den Klassen vorhandenen Attribute zurück und erstellt die XML-Daten nach diesen Vorgaben. Es fällt leicht, sich vorzustellen, dass keine Zeit im Projekt vorhanden ist, sich umfassend mit XML Schema zu beschäftigen und dann auch noch die XML Schema-Bindung zu lernen. Gleichzeitig kann man sich aber sicherlich auch sehr leicht vorstellen, wie schnell eine solchermaßen unkoordinierte und ungeplante Verwendung von XML, das möglicherweise auch noch die Grenzen der eigenen Anwendung verlässt, zu größtem Chaos führen kann. Irgendwann sind evtl. doch mehr Anforderungen für die Datenmodellierung vorhanden,
454
11
11. XML Schema und OOP
und dann muss man möglicherweise aus Kompatibilitätsgründen eine ungünstige Modellierung beibehalten und neue Strukturen mehr hineinquetschen als strukturiert ergänzen. Die nachfolgende Abbildung enthält die Struktur der generierten XML-Datei. Es handelt sich um das gleiche Programm wie zuvor, wobei jedoch das Klassensystem um sämtliche Attribute bereinigt wurde. Diese Lösung finden Sie im Projekt StandardXML zur Ansicht. Da keine Attribute zur Festlegung, wie das XML aussehen soll, mehr existieren, kann natürlich auch keine Unterscheidung zwischen XML-Elementen und XML-Attributen mehr vorgenommen werden. Auch eine Umbenennung zwischen .NET-Namen und XML-Namen ist nicht möglich. Besonders ärgerlich und verräterisch ist allerdings, dass der Klassenname ErfolgTyp noch einmal als weitere überflüssige Hierarchie-Ebene im XML vorhanden ist.
Abbildung 11.12:Über die Standard-Serialisierung generierte XML-Struktur
Auch eine XML Schema-Datei kann aus solchen Klassendefinitionen erzeugt werden. Hierzu kann man aus dem Projekt StandardXML die Datei StandardXML.exe verwenden. Da hier mehrere Klassen enthalten sind und ggf. auch mehrere Objektstrukturen definiert sein könnten, gibt man den Start-Typ über den letzten Parameter gesondert an. C:\...\xsd.exe „C:\...\StandardXML.exe“ „/o:C:\...\StandardXML“ „/t:Erfolguebersicht“
Wie schon die generierte XML-Datei nahe gelegt hat, entstehen aus allen Eigenschaften Kind-Elemente. Diese erscheinen in der Reihenfolge wie in der Klasse. Die Klassennamen selbst erscheinen als Namen der globalen komplexen Typen. Für die Wiederholung der ErfolgTyp -Elemente ist eine Hierarchie-Ebene zuviel erzeugt worden, welche in einem eigenen globalen komplexen Typ namens ArrayOfErfolgType enthalten ist.
455
11
11. XML Schema und OOP
Abbildung 11.13:Über Standard-XML-Serialisierung generiertes XML Schema
11. 3. XML-Schema-Bindung in Java Mit Hilfe von JAXB (Java Architecture for XML Binding) ist es in Java möglich, XML SchemaDateien an Java-Klassen zu binden und über wenige Programmzeilen zwischen objektorientierten Strukturen und XML-Daten zu wechseln. Mehr Informationen zu diesem Projekt finden Sie unter http://jaxb.java.net/. Es besitzt Unterstützung für die Generierung von Java-Klassen aus XML Schema-Daten heraus, den umgekehrten Weg, d. h. die Generierung von XML Schema-Dateien aus Java-Klassen, das Marshalling (Serialisierung von Objekten) und das Unmarshalling (Deserialisierung von XML in Objekte). Sofern Sie nicht ohnehin schon das Java EE-Framework auf Ihrem Rechner installiert haben, laden Sie sich von der Projekt-Seite die aktuelle Software herunter. Im bin-Ordner finden Sie dann die beiden benötigten Batch-Dateien jxc.bat (Java-Klassen aus XML Schema generieren) und schemagen.bat (XML Schema aus Java generieren).
456
11
11. XML Schema und OOP
11. 3. 1. Prinzip der Klassengenerierung aus XML Schema Die klassische Vorgehensweise besteht darin, zunächst zu testen, was überhaupt passiert, wenn man eine einfache XML Schema-Datei zu Klassen umwandelt. Die einfachste XML Schema-Datei ist dabei eine, die im Matrjoschka-Design erstellt wurde. Im nachfolgenden Beispiel ersetzen die drei Punkte jeweils den Pfad zur xjc.bat-Datei, zur XML Schema-Datei und zum Ausgabeordner. C:\...>xjc matrjoschka.xsd parsing a schema... compiling a schema...
generated\Erfolguebersicht.java generated\ObjectFactory.java
Die Verwendung des Generators ist relativ einfach, da er nur wenige Parameter besitzt bzw. auch nicht alle immer benötigt werden. Im allereinfachsten Fall genügt die Angabe des umzuwandelnden XML Schemas. Die allgemeine Syntax ist: xjc [-options ...] Folgende Optionen sind vorhanden: ●●
-nv: keine strikte Validierung des XML Schemas
●●
-extension: Erweiterungen verwenden, die über die JAXB-Spezifikation hinausgehen
●●
-b : Berücksichtigung von Konfigurationsdateien zur erweiterten Vorgabe von
Bindungsoptionen, wobei mehrere -b-Parameter/-Dateien genutzt werden können ●●
-d : Ausgabeverzeichnis
●●
-p : Ziel-Paket der generierten Dateien
●●
-classpath : weitere benutzerdefinierte Java-Klassen
●●
-readOnly: generierte Dateien sind nur lesbar (da sie nicht geändert werden sollen)
●●
-xmlschema: Verwendung von W3C XML Schema (Standard)
457
11
11. XML Schema und OOP
●●
-relaxng und -dtd: Verwendung von RELAX NG und XML DTD (experimentell)
●●
Allgemeines: -quiet (keine Textausgabe), -help (Hilfetext) und -version
Das XML Schema wird ausgelesen, und die erzeugten Java-Klassen finden Sie dann im generated-Ordner/Paket. Im Standardverfahren erzeugt der Generator eine einzige Klasse mit dem Namen des Wurzelelements, welche für jede Ebene im XML Schema-Dokument bzw. Matrjoschka-Design eine statische innere Klasse erzeugt. Die sehen Sie in der Abbildung, in welcher für jede Hierarchie-Ebene der entsprechende Klassenname eingetragen ist.
Abbildung 11.14: Matrjoschka-Design und generierte Klassen
Grundsätzlich ist dieses Verfahren nicht schlecht. Sollten Sie den Abschnitt über .NET auch gelesen haben, dann wissen Sie, dass dort die Standardlösung ist, einzelne Klassen zu erzeugen, wobei aber die Namen aus der sich aufbauenden Hierarchie abgeleitet werden, was natürlich zu erschreckend langen Klassennamen führen kann. Dies bleibt einem in Java erspart. Dafür muss man aber mit der doch eher umständlichen Notation für statische innere Klassen umgehen. In der Abbildung sehen Sie die generierten Klassen und ihre jeweilige Referenzierung.
458
11
11. XML Schema und OOP
Abbildung 11.15:Über Matrjoschka-Design generierte Klassen
11. 3. 2. XML Schema-Bindung Es macht also Sinn, dem Generator ein XML Schema zu liefern, welches zu Klassen führt, mit denen man auch tatsächlich nachher in einer Anwendung arbeiten möchte. Wie auch schon bei .NET ist es überaus zweckmäßig, für jede Hierarchieebene (nur evtl. nicht unbedingt für die oberste Ebene) einen globalen komplexen Typ zu erstellen. Aus jedem einzel-
459
11
11. XML Schema und OOP
nen von ihnen wird dann eine neue Klasse generiert. Auch die Vererbung zwischen UmsatzTyp und GesamtTyp wird in Java umgesetzt.
Abbildung 11.16: Globale komplexe Typen und daraus generierte Klassen
Der Aufruf des Generators bleibt weitestgehend gleich, allerdings haben wir als Beispiel noch ein Verzeichnis, das schon existieren muss und nicht vom Generator angelegt wird, angegeben. C:\...>xjc komplexeTypen.xsd -d KomplexeTypen parsing a schema... compiling a schema... generated\ErfolgTyp.java generated\Erfolguebersicht.java generated\GesamtTyp.java generated\ObjectFactory.java generated\UmsatzTyp.java
460
11
11. XML Schema und OOP
Abbildung 11.17:Über globale komplexe Typen generierte Klassen
Das entstehende Klassensystem sollte nun der Form entsprechen, die man mit Blick auf das XML Schema ohnehin erwarten würde:
461
11
11. XML Schema und OOP
●●
Für jede Hierarchie-Ebene erhält man eine eigene Klasse.
●●
Die Wiederholung des Erfolg-Elements ist in der Java-Abbildung eine generische Liste der entstehenden Erfolg-Klasse. Es gibt keine set()-Methode, sondern man verwendet die get()-Methode, um die Erfolg-Objekte abzurufen und dann über die add()-Methode der Liste ein neues Objekt einzufügen.
●●
Die Eigenschaften sind alle protected, damit man auf sie in Kind-Klassen zugreifen kann.
●●
Die Getter- und Setter-Methoden sind alle öffentlich.
●●
Aus Elementen und Attributen wurden Felder mit Getter-/Setter-Methoden.
●●
Es wurden passende Java-Datentypen für XML Schema-Datentypen verwendet.
In den generierten Dateien befindet sich noch die wichtige Warnung, dass man natürlich keine Änderungen an ihnen vornehmen soll. Erweiterungen der Klassen wie neue Eigenschaften oder Methoden müssen dann in Kind-Klassen ergänzt werden. Schließlich wurde hier und beim vorherigen Beispiel noch eine weitere Klasse erzeugt: die ObjectFactory, in der create()-Methoden enthalten sind, welche Instanzen der einzelnen Klassen erzeugen.
11. 3. 3. Mapping und Serialisierung beeinflussen Manchmal möchte man Strukturen genauer vorgeben oder ganz einfach das Standardverhalten der Bindung überschreiben. JAXB bietet zwei unterschiedliche Möglichkeiten, Bindungseinstellungen vorzugeben: ●●
462
11
Zum einen kann man aus Java-Klassen heraus XML Schema-Dateien generieren. Hierzu gibt es zwar viele Standardvorgaben, aber – wie Sie möglicherweise auch schon in vollständigen den Beispielen gesehen haben – in den Klassen setzt man Annotationen ein, um festzulegen, welche Eigenschaften zu Elementen oder Attributen werden sollen oder wie der Name von Klassen zu globalen komplexen Typen werden soll. Diese Annotationen haben wir in den vorherigen Abbildungen gelöscht, um nur die Strukturen der Klassen an sich anzugeben.
11. XML Schema und OOP
●●
Zum anderen gibt es die Möglichkeit, direkt in der XML Schema-Datei oder sogar in einer externen Bindungsdatei (aber im gleichen Format, was die Einstellungen anbetrifft) Angaben zu treffen, wie die Klassen aus einer XML Schema-Datei heraus generiert werden sollen.
Wichtig ist zu berücksichtigen, dass es nicht nur um die Generierung von Klassen oder XML Schema-Dateien geht, sondern diese ganzen Einstellungen ja auch jedes Mal bei der späteren Übertragung von Objekten oder XML-Daten ausgelesen und genutzt werden. Daher sind dies auch nicht ausschließlich Einstellungen für die Erzeugung, sondern auch solche für das (Un)Marshalling.
11. 3. 3. 1 Annotation in Java-Klassen Manchmal möchte man die Art der Zuordnung zwischen XML Schema und den Klassen genauer angeben oder aus bestehenden Klassen ein XML Schema erzeugen. Dazu kann man die Klassen mit Annotationen ausstatten, von denen wir einige in diesem Abschnitt kurz vorstellen. Mit XmType kann man für eine Klasse festlegen, welcher globale komplexe Typ erzeugt werden soll, ob er einen Namensraum besitzt (auch einzeln für Elemente definierbar) oder in welcher Reihenfolge die Eigenschaften der Klasse als XML-Elemente erscheinen sollen. Sämtliche Standardeinstellungen sind so gewählt, dass die Klasse „möglichst gut“ oder „möglichst ähnlich“ abgebildet wird. Dies bedeutet, dass zunächst die Klassennamen oder die bestehende Reihenfolge verwendet werden. @XmlType ( name = “##default”, propOrder = {“”}, namespace = “##default”, factoryClass = DEFAULT.class, factoryMethod = “” )
Mit XmlRootElement legt man dann den Namen für ein Element und seinen Namensraum fest. Man kann es auch ohne diese Angaben verwenden, um eine Eigenschaft als Element zu serialisieren. Dies wäre allerdings auch der Standard.
463
11
11. XML Schema und OOP
@XmlRootElement ( name = “##default”, )
namespace = “##default”
Mit XmlAccessorType legt man die Standardeinstellungen für Felder, Eigenschaften (haben Getter und Setter) oder einfach öffentliche Felder und Eigenschaften fest. @XmlAccessorType ( )
value = AccessType.PUBLIC_MEMBER | PROPERTY | FIELD | NONE
Nachfolgend sind die Einstellungen so gewählt, dass das bestehende XML Schema entsteht. Lediglich der Namensraum ist neu. import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) @XmlType( name = “”, propOrder = {“erfolg”}, namespace = “http://www.ruhrfon.biz” ) @XmlRootElement(name = “Erfolguebersicht”) public class Erfolguebersicht { @XmlElement(name = “Erfolg”, required = true) protected List erfolg; ... AnnotationenTest/Erfolguebersicht.java: Wurzelelement festlegen
Mit XmlElement legt man dann fest, dass diese Eigenschaft als Element serialisiert wird und kann Vorgaben für den Namen, fehlender Textknoten, den Namensraum und auch den Typ machen. Für einfache Datentypen gibt es eine Übertragung zwischen Java und XML Schema (Zeichenketten, Zahlen, Wahrheitswerte). Für komplexe wird natürlich die Klasse der Eigenschaft verwendet. @XmlElement (
464
11
11. XML Schema und OOP
name = „##default“, nillable = false,
namespace = „##default“, type = DEFAULT.class, )
defaultValue = „\u0000“
Ähnlich verhält es sich mit der Angabe XmlAttribute, wenn eine Eigenschaft als Attribut ausgegeben werden soll. Neben Namen und Namensraum kann man noch angeben, ob es optional oder verpflichtend ist. @XmlAttribute (
name = ##default, required = false,
)
namespace = „##default“
Die Einstellung XmlTransient ist besonders kurz, denn sie hat keine weiteren Angaben und legt nur fest, dass diese Eigenschaft nicht in XML erscheint. @XmlTransient
Nachfolgend sind die Einstellungen für die Kind-Elemente und Attribute des Erfolg-Elements zu finden. Sie entsprechen den Einstellungen im schon bekannten XML Schema. Lediglich eine weitere Eigenschaft ist neu in Java hinzugekommen, die aber nicht in XML ausgegeben wird. @XmlAccessorType(XmlAccessType.FIELD) @XmlType( name = “ErfolgTyp”, propOrder = { “gesamt”, “proKopf” } ) public class ErfolgTyp { @XmlElement(name = “Gesamt”, required = true) protected GesamtTyp gesamt; @XmlElement(name = “ProKopf”, required = true) protected UmsatzTyp proKopf; // Berücksichtigung mit anderem Namen
465
11
11. XML Schema und OOP
@XmlAttribute(name = “Ort”, required = true) protected String stadt; @XmlAttribute(name = “Monat”, required = true) protected String monat;
// Nicht berücksichtigen @XmlTransient private String region; ...
AnnotationenTest/ErfolgTyp.java: Angaben für Elemente und Attribute
Im Verzeichnis, in dem sich auch die Batch-Datei zur Verwendung des Klassengenerators befindet, gibt es eine weitere, mit der man aus Java-Klassen (.java oder .class) eine XML Schema-Datei erzeugen kann. Dies ist schemagen.bat mit einer wiederum einfachen Bedienung: schemagen [-options ...]
Folgende Optionen sind möglich. ●●
-d : Ausgabeverzeichnis
●●
-cp oder -classpath : Pfad zu weiteren Java-Dateien
●●
-help: Hilfetext
Weitere Informationen: http://jaxb.java.net/jaxb20-ea3/docs/schemagen.html
11. 3. 3. 2 Deklarationen für Klassenbindung in XML Schema Auch in XML Schema gibt es die Möglichkeit, Anmerkungen zu hinterlegen, mit denen die Generierung der Klassen und damit natürlich auch die Umwandlung der Objekte-/XMLDaten beeinflusst werden kann. Der wohl häufigste Grund ist ein Mapping zwischen Namen in XML und Java. Aber auch die Auflösung von möglichen Namenskollisionen, komplexe Vorgaben wie der Umgang mit Elementgruppen oder Übertragung von anonymen Typen/ Gruppen zu Klassen sind interessante Anwendungsgebiete. Man spricht hier von Anpassungen (engl. customizations) und unterscheidet interne und externe Anpassungen:
466
11
11. XML Schema und OOP
●●
Bei internen Anpassungen (engl. inline customization) trägt man die Anpassungen direkt in das XML Schema. Hierzu verwendet man innerhalb des xs:annotationElements das Kind-Element xs:appinfo. Dieses ist in der Lage, Elemente aus einem anderem Namensraum zu enthalten, sodass man hier deutlich mehr Informationen eintragen kann, als dies über Fremd-Attribute möglich wäre.
●●
Bei externen Anpassungen (engl. external binding customization files) befinden sich die Anpassungen in einer eigenen JAXB-Anpassungsdatei, wobei im Rahmen einer Generierung mehrere solcher Dateien über den –b-Parameter angegeben werden können. Diese folgen dem JAXB-Standard, benötigen allerdings keine bestimmte Endung. Es wird .xjb vorgeschlagen.
Die Möglichkeiten sind recht umfangreich und stehen darüber hinaus in einem hierarchischen Verhältnis zueinander. Standardvorgaben werden von globalen Vorgaben überschrieben, welche wiederum von lokalen Einstellungen außer Kraft gesetzt werden. Allgemeine Schema-Vorgaben betreffen die Erzeugung des Java-Pakets oder sogar mehrerer Java-Pakete, wenn eine Anpassungsdatei für mehrere XML Schema-Dokumente auf einmal gelten soll. Darüber hinaus enthalten sie Regelungen, welche die allgemeinen Benennungskonventionen überschreiben. [ package ] [ ... ]* Paket-Dokumentation für generiertes Paket “statistik”.]]>
komplexeTypen-Annotationen.xsd: Angaben für das XML Schema bzw. Paket
Für Elemente oder komplexe Typen ist es wichtig, die aus ihnen zu erzeugende Java-Klasse anzugeben. Elemente mit einem Textknoten sowie Attribute können dann zu Eigenschaften umgewandelt werden. Sowohl class wie auch property hat ein name-Attribut. Das Element property erlaubt es dann, bei Elementen mit mehrfachem Auftreten die Art der Collection anzugeben (Array oder Liste) und bei Attributen einen festen Wert auf eine Klassenkonstante zu mappen. [ ... ] Umsatz]]> ...
komplexeTypen-Annotationen.xsd: Umbenennen einer Klasse
469
11
11. XML Schema und OOP
Schließlich wird noch festgelegt, dass eine java.util.List als Collection für die mehrfach auftretenden Erfolg-Elemente verwendet wird. Diese wird auch in Java umbenannt, sodass im Namen schon deutlich wird, dass es sich um eine Liste handelt.
komplexeTypen-Annotationen.xsd: Angabe der Collection-Art
Dieses erweiterte XML Schema kann man dann ebenfalls mit xjc.bat in Java-Klassen umwandeln.
11. 3. 4. Von XML zu Objekten Nun fehlen noch zwei Beispiele, die zeigen, wie leicht man über diese gesamte Technik XML-Daten in Objekte umwandeln kann und auch wieder zurück von Objekten in XML gelangt.
11. 3. 4. 1 Marshalling Im ersten Beispiel erstellt man über die generierten Klassen eine verschachtelte Objektstruktur. Im Gegensatz zur Arbeit mit anderen XML-Bibliotheken wie bspw. mit dem DOM (Document Object Model) beschäftigt man sich im Quelltext überhaupt nicht damit, dass man später eine XML-Datei generieren will. Man kann auch den Aspekt der XML-Erstellung völlig außen vor lassen und zunächst weiter mit den Objekten arbeiten. Während man beim DOM von vornherein einen überaus langen und meist auch durch Wiederholung geprägten Quelltext erstellt, an dem man manchmal bei sehr tief verschachtelten Strukturen gar nicht mehr erkennen kann, was für eine XML-Struktur über Zeilen hinweg formuliert wird, arbeitet man nun nicht mit einer objektorientierten Dokument-Darstellung, sondern mit einer objektorientierten Daten-Darstellung.
470
11
11. XML Schema und OOP
Die einzelnen Objekte für die Bestandteile der Objektstruktur erstellt man über die create()-Methoden der Klasse ObjectFactory. // Erstellung einer Erfolgsübersicht
ObjectFactory of = new ObjectFactory(); Erfolguebersicht uebersicht = of.createErfolguebersicht(); GesamtTyp gesamt = of.createGesamtTyp(); gesamt.setAnrufe(BigDecimal.valueOf(18869)); gesamt.setUmsatz(BigDecimal.valueOf(7154.01)); gesamt.setKunden(200); UmsatzTyp proKopf = of.createUmsatzTyp(); proKopf.setAnrufe(BigDecimal.valueOf(94.35)); proKopf.setUmsatz(BigDecimal.valueOf(35.77)); ErfolgTyp erfolg = of.createErfolgTyp(); erfolg.setMonat(„10.04“); erfolg.setStadt(„Essen, Ruhr“); erfolg.setGesamt(gesamt); erfolg.setProKopf(proKopf); uebersicht.getErfolg().add(erfolg); MarshallingTest.java: Erstellung der Objektstruktur
Man benötigt verschiedene Importe, die nachfolgende aufgelistet sind: import import import import
javax.xml.bind.JAXBContext; javax.xml.bind.JAXBException; javax.xml.bind.Marshaller; javax.xml.bind.Unmarshaller;
Man erstellt zunächst einen JAXBContext, der mit dem Namen des Pakets initialisiert wird, in welchem die verschiedenen Klassen zu finden sind, die beim (Un)Marshalling genutzt werden. Für das Marshalling steht die Klasse Marshaller zur Verfügung, während analog Unmarshaller für den Weg von XML in Objekte genutzt wird. Der Marshaller hat verschiedene Optionen, die über die Methode setProperty() und die Verwendung einer Konstanten gesetzt werden. Zu ihnen zählen JAXB _ ENCODING (String), JAXB _ FOR-
471
11
11. XML Schema und OOP
MATTED _ OUTPUT (Formatierung des XML ein-/ausschalten, Boolean), JAXB _ SCHEMA _ LOCATION (Angabe von xsi:schemaLocation im XML, String) oder JAXB _ NO _ NA-
MESPACE _ SCHEMA _ LOCATION (analog). Die Methode marshal() ist – wie nicht anders
zu erwarten – in vielen überladenen Varianten vorhanden, damit verschiedene Ausgaben leicht verwendet werden können. // Serialisierung
try { JAXBContext jc = JAXBContext.newInstance(„generated“); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
}
m.marshal(uebersicht, new File(„erfolguebersicht.xml“));
catch (JAXBException e){ e.printStackTrace(); }
MarshallingTest.java: Durchführung der Serialisierung
11. 3. 4. 2 Unmarshalling Der umgekehrte Weg ist ebenfalls sehr einfach. Die gerade erzeugte XML-Datei wird über den nachfolgenden Vorgang wieder in eine Objektstruktur eingelesen und kann dann wieder über die Eigenschaften/Felder angesprochen werden. Hätte man noch weitere Methoden oder Eigenschaften in partiellen Klassen erstellt, so könnte man diese ebenfalls für die Weiterverarbeitung nutzen. Wie oben schon erwähnt, ist erneut ein Objekt vom Typ JAXBContext, initialisiert mit dem Paket, welches die zu erzeugenden Klassen enthält, notwendig. Nun erstellt man ein Unmarshaller-Objekt, dessen entscheidende Methode selbstverständlich unmarshal() ist, die in vielen überladenen Varianten existiert. try { // Deserialisierung JAXBContext jc = JAXBContext.newInstance(„generated“); Unmarshaller u = jc.createUnmarshaller(); Erfolguebersicht uebersicht = (Erfolguebersicht)u.
472
11
11. XML Schema und OOP
unmarshal( new FileInputStream(„erfolguebersicht.xml“)); // Ausgabe und Weiterverwendung Iterator iter =
uebersicht.getErfolg().iterator();
while (iter.hasNext()){ ErfolgTyp erfolg = iter.next();
System.out.println(„Anrufe gesamt: „
+ erfolg.getGesamt().getAnrufe()); System.out.println(„Anrufe pro Kopf: „
}
}
+ erfolg.getProKopf().getAnrufe());
catch (JAXBException e){ e.printStackTrace(); }
catch (FileNotFoundException e){ e.printStackTrace(); } MarshallingTest.java: Deserialisierung von XML in Objekte
JAXB bietet sehr viele fortgeschrittene Erweiterungsmöglichkeiten, mit denen man umfassend in die Prozesse der Erstellung von XML Schema oder Klassen eingreifen kann, um die vielen verschiedenen Optionen, die XML Schema bietet, oder die bei der Modellierung in einem konkreten Fall notwendig sind, umsetzen zu können. Darüber hinaus kann man auch in die Prozesse der Daten-Umwandlung selbst eingreifen und Standardverhalten überschreiben oder zusätzliche Logik einbauen.
473
11
Index
Index
Index
Symbols
Ableitung durch Einschränkung 103 Ableitung durch Liste 103 Ableitung durch Vereinigung 103 #all 278, 280, 281, 282 #all 103 ##any 315 ##local 315 Matrjoschka-Design 208 .NET 429 ##other 315 ##targetNamespace 315
A
Abgeleitete Datentypen 76 Abhängigkeitstypen 321 Ableitung 330 Attributgruppe 239 Durch Einschränkung 333 Durch Erweiterung 333 Einschränkung 109, 152, 162, 181, 236 Erweiterung 148, 181 Erweiterung 233 Grundproblem 275 Liste 111 Namensraum 241 Techniken 147 Vereinigung 112 von einfachem Inhalt 136 Ableitung 109
Ableitungen 103 Ableitungen kontrollieren 275 Ableitungskontrolle 358 Einfache Typen 280 Elemente 278 Komplexe Typen 279 Schema-Standardeinstellung 281 Ableitungstechniken 277 abstract 267 abstract 264 Abstraktes Element 267 Abstraktes Element 264 ADO 384 all 168 ALL_XML_SCHEMAS 420 ALL_XML_TAB_COLS 420 ALL_XML_TABLES 420 ALL_XML_VIEW_COLS 420 ALL_XML_VIEWS 420 Anforderungen an Schema-Sprachen 40 Anmerkung 363 annotation 363, 467 Annotation in Java-Klassen 463 Anpassungen in JAXB 466 any 315 anyAttribute 315 anyType 268 anyURI 72 appinfo 364, 467 attribute 47, 52
475
Index
Attribute 47, 56, 334, 339, 387 Globale Deklaration 50 Lokale Deklaration 47 Attribute 46 Element-Ersetzungsgruppe 274 attributeFormDefault 246, 296 attributeGroup 178, 256 attributeGroup 169 Attributgruppe Ableitung 239 Attributgruppen 178, 256 Attributgruppen 261 Attributorientierte Dokumente 65 Auslagerung 105 Auslagerungstechniken 116 Auslagerung und Wiederverwendung 326, 330, 348, 357 Ableitungsgkontrolle 275 Ersetzungsgruppen 257 Globale Elemente und Attribute 255 Import 242 Import mit eigenem Namensraum 251 Übernahme ohne Namensraum 249 Auslagerung und Wiederverwendung 227 Gruppen 255 Auslesen von Kommentaren 369 Fremd-Attribute 379 XHTML nach HTML 377 Auslesen von XML-Kommentaren 370 Auslesen von XML-Schema-Kommentaren In HTML 375 In Textdatei 373 Auswahl 166
B
Babuschka. Siehe Matrjoschka Babuschka-Design 294, 296, 301, 357 base 102, 109, 238 base64Binary 74
476
Basistyp 102 Baumdiagramm-Ansatz 29 Beliebige Inhalte akzeptieren 314 Beziehungen 39, 55 block 278, 279 block 277 blockDefault 281 Blockdiagramm-Ansatz 28 boolean 72 bounded 90
C
cardinality 90 Chamäleon-Design 311 Charakterisierung von Elementen 21 choice 166 complexContent 155 complexType 44, 129, 160, 171, 176, 180 complexType 128 createNonSchemaBasedXML() 417 createSchemaBasedXML() 417 CREATE XML SCHEMA COLLECTION 421
D
Data Dictionary-Sichten MS SQL Server 426 Oracle 420 date 73 Datenbank 324 XML Schema-/Klassen-Mapping 438 Datenbank-Datenmodellierung 384 Datenbanken MS SQL Server 421 Oracle 411 XML-Tabelle in Oracle 415 Datenbanken und XML 409 Datenbeschreibung 386 Datenmodellierung 384 Datenorientierung 337
Index
Dokumentenmodellierung 337 Datenmodellierung 387, 389 Datenorientierung 54, 337 Datenstruktur 64 Datentypen Abgeleitet 76 Ableitung 88 Basistyp 102 Binärdaten 74 Eigene 102 Globale 105 Listentypen 81 Logik 72 Vordefinierte 71 Zahlen 72, 79 Zeichenketten 72, 77 Zeitangaben 73 Datentypen 347, 384 Datentypen durch Ableitung deklarieren 109 dateTime 73 DBMS_XMLSCHEMA 411 DB-Strukturen 389 DDL 386 decimal 72 Definition von Eindeutigkeit 215 Definition von Schlüsseln 204 deleteSchema() 413 Deserialisierung 435 Design-Alternativen 357 Direkter Inhalt 156 DocBook 23 documentation 364, 377 Dokumentation 360, 361 Dokumentenorientierung 54, 337 Dokumentmodellierung 39, 320, 331, 333 Attribute 56 Attributorientierte vs. elementorientierte Technik 65
Baumdiagramm 29 Bewertungskriterien verschiedener Techniken 63 Blockdiagramm 28 Datenorientierung 54 Dokumentenorientiert 179 Dokumentenorientierung 54 Erweitertes Baumdiagramm 30 Schlüssel 194 Syntax-Änderungen 321 Techniken im Vergleich 58 Dokumenttypen 24 DOM 322, 452 double 72 DTD 10, 131 Schlüssel 194 duration 73
E
Eigene Datentypen 102 Eindeutigkeitsbeschränkung 214 Einfache Inhalte 155 Einfacher Inhalt Ableitung durch Einschränkung 139, 162 Ableitung durch Erweiterung 137 Einfache Typen 330 Einfache Wiederverwendung 228 Einschränkende Fassetten 91 Einzigartigkeitsbeschränkung bei Auswahl 219 element 43, 49 Element-Benennung 334 Elemente 334, 387 Globale Deklaration 49 Element-Ersetzungsgruppe 274 Element-Ersetzungsgruppen 262 elementFormDefault 246, 296 Elementgruppen 171, 256 Elementgruppen 259
477
Index
Elementorientierte Dokumente 65 ENTITIES 79 ENTITY 78 Entwicklungsphase in XML-Projekten 21 enumeration 96 equal 90 ER-Modell 386 Ersetzungsgruppen 269 Ersetzungsgruppen für Elemente 257 Erweiterbare Schemata 333, 357 Erweiterbarkeit 357 Erweitertes Baumdiagramm 30 Existenz 328 extension 278, 280, 281, 282 extension 135 Extraktion von XML-Kommentaren 372
F
Fassetten Definition 88 Dezimalaufteilung 100 Einschränkende Fassetten 91 Grenzen und Schranken 98 Grundlegende Fassetten 90 Längenangaben 93 Wertmuster 95 field 205, 402 final 278, 279 final 277 finalDefault 282 float 72 FO 23 form 246 fractionDigits 101 Fremd-Attribute 368
G
gDay 74 Gemischte Inhaltsmodelle 179
478
Gemischter Inhalt 129 Ableitung durch Einschränkung 181 Ableitung durch Erweiterung 181 getNamespace() 418 getRootElement() 418 getSchemaURL() 418 Globale Deklaration 48, 49, 128 Globale Komponenten 357 gMonth 74 gMonthDay xs gMonthDay 74 group 171, 176 group 166, 169, 255 Gründe für die Verwendung von globalen Datentypen 105 Grundlegende Fassetten 90 Gruppen 169 Attribute 178 Elemente 171 Gruppierungen 255, 330 Gültig 25 Gültigkeitsbereiche von Schlüsseln 211 gYear 74 gYearMonth 73
H
Häufigkeit 130 hexBinary 74 Hierarchie 55, 329 Hierarchie 339, 353 Hierarchiebeziehungen 329 HTML 20, 324
I
IBM DB2 415 ID 78, 193, 197 Identifikation 105 Identifikation von Elementen 21
Index
Identität 39, 55 IDREF 197 IDREF 78 IDREFS 78 IDREFS 199 import 243, 310 Import 357 Import 242, 251, 275, 301, 307, 333 Import-/Export-Schnittstellen 410 include 227 Inhaltsmodell 20, 39 Einfache Inhalte 155 Inhaltsmodelle 155 Auswahl 166 Gemischte Inhaltsmodelle 179 Gruppenbildung 169 Reihenfolge 163 Zusammenstellung 168 Inklusion 275, 333 Inklusion 227, 301, 311, 312, 357 Instanzdokument 24, 31 int 79 integer 79 isSchemaBased() 417 isSchemaValid() 417 isSchemaValidated() 417 itemType 111
J
Java 429 jaxb class 468 nameXmlTransform 467 package 467 property 468 schemaBindings 467 JAXB 456 JAXBContext 471
K
Kardinalität 39, 55, 130, 328 key 204, 295 key 399 keyref 295, 400 keyref 399 Knotenlokalisierung 64, 68 Kommagetrennte Werte 324 Kommentare 368 Kommentar-Elemente 363 Komplexe Inhalte 163 Komplexen Typen 128 Komplexe Typen 330, 345 Ableitung durch Einschränkung 152 Ableitung durch Erweiterung 148 Globale komplexe Typen 141 Lokale komplexe Typen 128 Kopf-Element 267, 277
L
language 77 lax 315 Leerzeichenbehandlung 97 length 93 Lesbarkeit 63 list 280, 282 Liste 111 Listentypen 81 Beispiel 83 Lokale Deklaration 47, 128 Lokale komplexe Typen 128 Lokalisierung 64, 68 long 79
M
Mapping zwischen XML und Objekten 431 Marshalling 435 Java 470 .NET 452
479
Index
Übersicht 434 Matrjoschka-Design 129, 133, 440 maxExclusive 98 maxInclusive 98 maxLength 94 maxOccurs 52, 131 maxOccurs 152, 164 Mehrfache Einfügung von Dokumenten 242 Mehrfachverweise 199 memberTypes 112 minExclusive 99 Minimalanforderungen an Inhaltsmodelle 40 minInclusive 99 minLength 93 minOccurs 131, 152 minOccurs 164 mixed 180 Modellierung 21, 26 MS SQL Server 410 Data Dictionary-Sichten 426 Typisiertes XML 423 XML Schema registrieren 421
N
name 102 Name 78 Namensraum 418 Namensräume 241, 377 Chamäleon-Design 311 Keine Übernahme 311 Verwendung eines einzigen Namensraums 288 Verwendung mehrerer Namensräume 300 Namensräume 251, 287 Übernahme 306 Verwendung bei globalen
480
Komponenten 304 namespace 303, 315 namespace 243 NCName 78 negativeInteger 79 NMTOKEN 78 NMTOKENS 78 nonNegativeInteger 80 nonPositiveInteger 79 normalizedString 77 NOTATION 72 numeric 90
O
OASIS 11 ObjectFactory 462, 471 Objektorientierung 430 Objekttypen generieren 412 ODBC 384 Oracle 406, 410 Data Dictionary-Sichten 420 Relationale Daten in XML 415 SQL/XML-Funktionen 415 Typisiertes XML 416 XML Schema registrieren 411 XMLType-Tabelle 415 XSLT, XPath und XQuery 419 Oracle 389 ordered 90 OR-Modell 386
P
pattern 95 pattern 118 PDF 23, 324 positiveInteger 80 processContents 315 Projektphasen bei XML-Einsatz 22 Projektphasen eines XML-Projekts 15
Index
Prüfung 25
Q
QName 72
R
RDF 322 redefine 227 redefine 233 Redefinition 233, 301 Redefinition 275, 311, 313, 357 ref 50, 52, 171, 176, 261, 277 refer 220 Reformulierung Mit Eigenschaftsänderung 328 Ohne Eigenschaftsänderung 330 Reformulierung Ohne Eigenschaftsänderung 328 Regeldokument 24, 33 registerSchema() 411 registerURI() 413 Reguläre Ausdrücke 118 Einfache Muster 118 Kurzschreibweisen 122 Meta-Zeichen 120 Zusammengesetzte Muster 119 Reihenfolge 39, 55, 163, 329 Relationale Daten in XML Oracle 415 Relationalen Daten in XML MS SQL Server 423 RelaxNG 11 restriction 238, 278, 281, 282 restriction 102, 135, 152, 280
S
SAX 322 Schema-Dokument 24 schemagen.bat 466
schemaLocation 303, 310 schemaLocation 243 schemaValidate() 417 Schlüssel 199, 203 ID und IDREF 193 Schlüssel 205, 209 selector 205, 402 sequence 132 sequence 164 Serialisierung 435 setSchemaValidated() 417 SGML 11 short 79 simpleContent 155 simpleContent 135 simpleType 102, 104, 112, 160 simpleType 109 skip 315 source 364 Speicherung von XML 410 Spezialisierung 106 SQL 364, 384, 386, 392, 406, 408 SQL/XML-Funktionen 415 Standard DocBook 23 DTD 10 FO 23 HTML 20 PDF 23 RelaxNG 11 SGML 11 XDR 10 XML 11, 21 XSL-FO 23 XSLT 11 Standardnamensraum 289 strict 315 string 72 Strukturänderungen 328
481
Index
substitution 278 substitution 281 substitutionGroup 262, 268 substitutionGroup 257 SVG 364 Syntax-Änderungen 326 Syntax-Änderungen in XML-Schema 321 sys.xml_schema_collections 426 sys.xml_schema_namespaces 426
T
unsignedInt 80 unsignedLong 80 unsignedShort 80 Untypisiertes XML 418 use 152 USER_XML_SCHEMAS 420 USER_XML_TAB_COLS 420 USER_XML_TABLES 420 USER_XML_VIEW_COLS 420 USER_XML_VIEWS 420
Tabellenfelder Als Attribute 388, 398 Als Kind-Elemente 394 Kind-Elemente 387 targetNamenspace 242 targetNamespace 243, 294, 303 Textknoten 156 time 73 token 77 Tokenliste 202 totalDigits 100 Transformation in SQL 394 Transformationsdokument 24, 35 type 144, 255, 277 Typisiertes XML 416, 423
V
U
W
Übernahme ohne Namensraum 249 UML 429 union 112, 280 union 282 unique 204, 214 unique 295 Unmarshalling 435 Java 472 .NET 453 Übersicht 434 unsignedByte 80
482
Validierung 22, 25 Gültig 25 Wohlgeformt 25 Verflechtung von Elementen 21 Vergleich DTD und XML-Schema 41, 43, 47, 85, 130, 193, 196, 200, 294, 332 Verweise auf Eindeutigkeits beschränkungen 220 Verweise auf Schlüssel 220 Verwendung von einem einzigen Namensraum 288 Verwendung von globalen Datentypen 105 VisualXSD 440 Vordefinierte Datentypen 71
W3C 10 whiteSpace 97 Wiederverwendung mit Redefinition 233 Wohlgeformt 25 Wurzelelement 418
X
XDR 10 XHTML 377 XHTML-Daten 366 xjc.bat 457
Index
xml lang 364 XML 11, 21, 322 Buchempfehlungen 14 Gültig 25 Projektphasen 15 Wohlgeformt 25 XmlAttribute Java 465 .NET 447 XML-Daten in Objekte 429 XML-Eingabestrom 24 XmlElement Java 464 .NET 446 XML-Kommentare 361 XML-Kommentaren 370 xmllang 288 xmlns 288, 294, 296 XmlRoot 445 XmlRootElement 464 XML Schema MS SQL Server 421 Oracle 411 URL 418 Vergleich mit Klassen 433 XMLSchema Verrweise zu den Standards 13 XML Schema-Klassen-Bindung 435, 441, 443, 458, 460 XML Schema-OO-Mapping Java 466 Java-Annotationen 462 .NET-Attribute 444 XmlSerializer 454 XML Spy 133 XMLSpy 366, 384, 386 XML Topic Maps 322 XmlTransient 465
XmlType .NET 445 XmType Java 463 XPath 64, 68, 173, 206, 221, 246, 262, 290, 354, 371, 373, 377, 380, 401 XPath 295, 328 xs all 168 annotation 363 any 315 anyAttribute 315 anyType 268 anyURI 72 appinfo 364 attribute 47, 52 attributeGroup 169, 178, 256 base64Binary 74 boolean 72 choice 166 complexContent 155 complexType 44, 128, 129, 160, 176, 180 date 73 dateTime 73 decimal 72 double 72 duration 73 element 43, 49 ENTITIES 79 ENTITY 78 enumeration 96 extension 135 field 205, 402 float 72 fractionDigits 101 gDay 74 gMonth 74 group 166, 169, 171, 176, 255 gYear 74
483
Index
gYearMonth 73 hexBinary 74 ID 78, 197 IDREF 78 IDREF 197 IDREFS 199 IDREFS 78 import 243 include 227 int 79 integer 79 key 204, 295, 399 keyref 295, 399, 400 language 77 length 93 long 79 maxExclusive 98 maxInclusive 98 maxLength 94 maxOccurs 164 minExclusive 99 minInclusive 99 minLength 93 minOccurs 164 Name 78 NCName 78 negativeInteger 79 NMTOKEN 78 NMTOKENS 78 nonNegativeInteger 80 nonPositiveInteger 79 normalizedString 77 NOTATION 72 pattern 95, 118 positiveInteger 80 QName 72 redefine 227, 233 restriction 135, 152 selector 205, 402
484
sequence 132, 164 short 79 simpleContent 135, 155 simpleType 102, 104, 112, 160 string 72 time 73 token 77 totalDigits 100 union 112 unique 204, 214 unique 295 unsignedByte 80 unsignedInt 80 unsignedLong 80 unsignedShort 80 whiteSpace 97 xs\ annotation 467 appinfo 467 XSD.exe 439, 449 XSL 23 XSL-FO 23 XSLT 11, 375, 386, 394 XSLT 15, 37, 243, 295, 400
Z
Zerlegung von XML 410 Zusammenstellung 168
Unsere Empfehlungen
Die • Empfehlung des Hauses •
Empfehlungen
XML: Standards und Technologien
Skulschus Wiederstein Themen • Einführung in XML: Definition, Architektur, Einsatzbereiche • Modellierung mit der Document Type Definition (DTD) und XML Schema • Filtern und lokalisieren mit XPath • Abfragen und umwandeln mit XQuery • Abfragen, umwandeln, darstellen und verarbeiten mit XSLT • Druckformate darstellen mit XSL-FO • (Objekt)relationale Datenbanken und XML – MS SQL Server und Oracle • Architektur und Techniken von Webservices: Definition, Einsatz, SOAP und WSDL 416 Seiten, € 39,95 ISBN: 978-3-939701-21-7
Inhalt
XML (eXtensible Markup Language) ist seit mehreren Jahren als Technologie für die Abbildung, den Transport und die Speicherung von strukturierten Daten etabliert und stellt in immer mehr IT-Prozessen und Anwendungen einen wesentlichen Baustein dar. Dieses Buch erklärt die gängigen Standards und Technologien, die im Bereich XML eingesetzt werden, liefert dabei zu jedem Thema viele Syntax-Beispiele und gibt Hinweise zum richtigen Einsatz. Sie lernen die beiden Standards DTD und XML Schema für die Modellierung und Validierung von XML-Daten kennen. Mit Pfadausdrücken in XPath sehen Sie, wie Sie Knoten lokalisieren und XML-Strukturen filtern, während Sie mit XQuery ganz neue XML-Dokumente auf Basis von SQL-ähnlichen Abfragen erzeugen. Die tatsächliche Umwandlung von XML sehen Sie anhand von XSLT für HTML, XML und Text und anhand von XSL-FO für Druckformate wie PDF. Serviceorientierte Architekturen werden mit Webservices aufgebaut, die ebenfalls in diesem Buch mit einer allgemeinen Beschreibung und den beiden wesentlichen Standards SOAP und WSDL eingeführt werden.
486
Empfehlungen
XSL-FO
Skulschus Kozik Wiederstein Themen • Seitenvorlagen, Seitenverlaufsvorlagen und Dokumentaufbau Blöcke und Gebiete, Tabellen und Listen • Zeichen- und Absatzformatierung, Grafik und Farbe • Bucherstellung, Inhaltsverzeichnis, Verweise und Links, lebende Kolumnentitel, Seiten- und Absatzkontrolle • Wieder verwendbare Komponenten • Einsatz in .NET und Java 300 Seiten, € 24,95 ISBN: 978-3-939701-17-0
Inhalt XSL-FO (eXtensible Stylesheet Language / Formatting Objects) ist eine W3C-Syntax, die speziell für die Transformation von XML-Dokumenten in PDF- und andere Druck-Formate geschaffen wurde. Dabei stellen die Formatierungsobjekte eine Zwischenschicht dar, in der die XML-Daten zunächst umgewandelt werden, bevor sie mit einem geeigneten Prozessor in hr Zielformat gebracht werden. Dieses Buch enthält alles, was man zum Einsatz von XSLFO benötigt: eine Darstellung des Standards, sehr viele Beispieldateien, Schemazeichnungen zum besseren Verständnis und Referenzen. XSL-FO-Prozessoren sind kostenlos und – je nach Anforderung – kostenpflichtig erhältlich. Dieses Buch setzt den Open Source-Prozessor Apache FOP ein und zeigt seine Verwendung in Java und .NET. XSL-FO entfaltet mit den beiden anderen Standards XSLT und XPath seine wahre Größe, da so die Möglichkeit besteht, komplexe Transformationen und Algorithmen zur Umwandlung zu erzeugen, die ebenfalls in XSLT eingebettet sind und anstelle von typischen HTML-Ausgaben nun PDF erzeugen können.
487
Empfehlungen
XSLT, XPath und XQuery
Skulschus Wiederstein Winterstone Themen • XSLT 1.0:Vorlagen/Templates, Kontrollanweisungen,Variablen und Parameter, Sortierungen und Gruppierungen, Ausgaben in HTML, Text/ CSV und XML • XSLT 2.0: Stylesheet-Funktionen, dynamisches XSLT, 2.0-Besonderheiten, Integration von XML Schema, strukturgetriebene Verarbeitung • XPath 1.0: Grundlagen, Knoten lokalisieren und filtern, Funktionsbibliothek • XPath 2.0: Kontrollanweisungen, 2.0-Besonderheiten und –Funktionen • XQuery 1.0: Abfragen und Umwandlung als Ersatz von XSLT/XPath • Integration: Einsatz in .NET, Java, PHP und Datenbanken (Oracle PL/SQL, MS SQL Server T-SQL)
470 Seiten, € 44,95 ISBN: 978-3-939701-50-7
Inhalt XSLT (eXtensible Stylesheet Language for Transformations) ist eine W3C-Syntax, die speziell für die Transformation von XML-Dokumenten geschaffen wurde. Mit XSLT können XMLDokumente in Formate wie HTML, Text und andere XML-Formate transformiert werden. Diese Technologie lässt sich in (fast) allen Programmiersprachen und in vielen Datenbanken nutzen und stellt die beste Möglichkeit dar, aus mehreren Anwendungen heraus die gleiche XML-Transformation aufzurufen. XPath setzt man als in XSLT eingebettete Pfadbeschreibungssprache für Lokalisierung, Filterung und Bearbeitung von XML-Knoten ein. XQuery teilt sich mit XPath die Funktionsbibliothek und bietet als „SQL für XML“ die Möglichkeit, im Rahmen einer Abfrage komplexe Ausgabeströme in XML anzugeben und stellt so eine verkürzte Technik für XSLT und XPath dar. Dieses Buch führt Einsteiger durch die genannten Umwandlungstechniken.
488
Skulschus | Wiederstein | Winterstone
XML Schema Themen
Verlag
• Modellierung von einfachen XML-Strukturen mit XML Schema • Typbibliothek von XML Schema und Erstellung eigener abgeleiteter Datentypen • Komplexe Inhaltsmodelle und globale komplexe Datenstrukturen und Vererbung • Schlüssel und Verweise in XML-Dokumenten definieren • Auslagerung und Wiederverwendung • Deklaration und Verwendung von Namensräumen • Beschreibung von Datenbankmodellen mit XML Schema • Generierung von SQL mit Hilfe von XSLT aus XML Schema • Verwendung von XML Schema in Oracle und MS SQL Server
Comelio Medien gehört zur Comelio GmbH, einem in Europa und den USA arbeitenden IT-Unternehmen. Der Verlag bietet den Mitarbeitern der Comelio GmbH die Gelegenheit, Technologien aus ihren Projekten in Buchform aufzubereiten und ihr Wissen der Entwicklergemeinde zur Verfügung zu stellen. An verschiedenen Standorten führen sie auch Seminare zu ihren Themen durch.
Inhalt
Autoren
XML Schema ist der W3C-Nachfolger zur Document Type Definition (DTD). Er stellt die Definition von datenorientierten Dokumenten in den Vordergrund und bietet umfangreiche Möglichkeiten, feine Angaben zu XML-Strukturen zu treffen. Mit diesem Buch erhalten Sie eine vollständige Einführung in XML Schema, sodass Sie in der Lage sind, eigene SchemaDefinitionen unter Anwendung aller Mechanismen zu erstellen. Dazu gehören Definition von Elementen und Attributen, Zuweisung und Erstellung von Datentypen, Auslagerung und Wiederverwendung von Teil-Dokumenten und Ableitung von globalen Strukturen oder auch den Einsatz von Schlüsseln und Verweisen. Sie lernen auch, wie Sie XML Schema-Dokumente für die Beschreibung von Datenbankstrukturen verwenden und diese mit XSLT in SQL-Quelltext transformieren können. Dabei unterstützen Sie Beispiele aus dem Umfeld einer Spielfirma, Vergleiche mit der DTD und die Abbildung von Syntaxstrukturen in Zeichnungen.
Marco Skulschus, Marcus Wiederstein und Sarah Winterstone arbeiten im Bereich Softwareentwicklung und Weiterbildung bei der Comelio GmbH. Sie beschäftigen sich seit Beginn der XML-Zeitrechnung mit
Internet Auf der Webseite zum Buch finden Sie alle XML-, DTD- und XML Schema-Dateien zum Download.
Einsteiger
Medien www.comelio-medien.com
Fortgeschrittene © 2011 Comelio GmbH
diesem Thema. Spezialgebiete sind hierbei Datenbanken und XML sowie Ontologien auf XML-Basis. Dies ist ihr zehntes Buch zum Thema XML mit Verkaufszahlen über 15.000 Exemplaren. Bis jetzt liegen Bücher zu einzelnen XML-Standards und zur Verwendung von XML in Datenbanken vor. Ihre Kurzreferenzen zu vielen XML-Themen verkauften sich über 40.000 mal.
Ebenfalls erhältlich: XSLT, XPath und XQuery ISBN 978-3-939701-50-7
Profis
29,95 € (D) ISBN 978-3-939701-57-6
9 783939 701576