back to top   1  Dokumente und Daten...

 

Das Akronym XML ist derzeit in aller Munde...
Es hat Einzug in fast jede Produktankündigung jüngerer Zeit gefunden, und keine neuere IT-Entwicklung, die nicht XML enabled wäre.

Es scheint, daß sich anhand XML dieselbe übersteigerte (und nicht notwendigerweise immer mit wahrheitsgemäßen Versprechungen arbeitende) Marketing-Euphorie (engl. hype) vollzieht, die bereits für das Schlagwort Objektorientierung zu beobachten war.
Die fachlichen Einschätzungen des Themas XML reichen von ASCII des 21 Jahrhunderts (H. S. Thomson) bis hin zur (berechtigten) kritischen Hinterfragung des Neuheitswertes, insbesondere im Vergleich zu bekannten Lösungen wie troff, LaTeX oder das Rich Text Format (RTF).

Zur Illustration der Bandbreite der Bedeutungs- und Anwendungszuschreibungen die XML zuteil werden sind nachfolgend einige willkürlich ausgewählte Pressezitate versammelt:

Schon die Spannweite dieser Definitionen läßt die Bedeutung des Themas „XML“ erahnen. Hervorzuheben ist, daß sich offensichtlich nicht nur technisch-fokussierte Blätter des dreibuchstabigen Akronyms annehmen.
Allgemein scheint XML vorzugsweise im Kontext World Wide Web (manchmal auch schlicht zum „Internet“ verallgemeinert) Beachtung zu finden.

Das erste Kapitel dieser Vorlesung bietet einen Einstieg in die XML-Welt anhand der zugrundeliegenden technischen Basiskonzepte.
Hierzu wird zunächst die Historie strukturierter Auszeichnungssprachen (engl. markup language) beleuchtet, und die Vorläufer der Markup-Sprache XML vorgestellt.
Desweiteren werden die grundlegenden syntaktischen Konstrukte des XML Standards anhand verschiedener Beispiele eingeführt. Die notwendige Begriffsbildung erfolgt auf Basis des XML Information Set.
Ein weiteres Teilkapitel motiviert die Notwendigkeit der XML-Namensräume zur Unterscheidung verschiedener XML-Vokabulare und als Voraussetzung der XML-basierten Inhaltssyndikatisierung.
Daran schließt sich die Betrachtung der Grammatik eines XML-Dokuments an. Hierzu wird der klassischen Mechanismus der Document Type Definitions (DTD) eingeführt. Schwerpunkt liegt jedoch auf der Diskussion der XML Schema Description Language (XSD), durch welche die strukturellen und inhaltlichen Ausdrucksmöglichkeiten der DTDs entscheidend erweitert werden.
Zum Abschluß des Kapitels wird mit der XML Hyper Text Markup Language (XHTML) die vermutlich bekannteste Auszeichnungssprache, welche zur Grundlage des World Wide Webs wurde, unter dem Blickwinkel XML besprochen.

1.1   Einführung und Überblick

Im Grunde besitzt die Geschichte der eXtensible Markup Language zwei Anfänge. Einerseits stellt XML die evolutionäre Fortentwicklung existierender generischer Auszeichungssprachen dar; andererseits sind die Hintergründe der Sprache XML so eng mit dem Aufkommen des World Wide Webs (WWW) verwoben, daß die Geschichte auch hier ihren Anfang nehmen könnte...

Der chronologischen Ordnung folgend sei zunächst die Entwicklung aus der Idee des Hypertext aufgerissen.
Die ersten Ideen zum Konzept des Hypertexts, als Plan zur Überwindung der Beschränkungen und Unzulänglichkeiten des klassischen textbasierten Publikationsmediums Papier, datieren zurück bis in die 1950er Jahre. Sie postulieren neben der nichtsequentiellen Organisation des Mediums auch zentrale Begriffe wie Knoten, Link, Anker und Netz. Ziel dieser Überlegungen war es, den auszudrückenden Inhalt von editorieller- und Präsentationsinformation wie Seitenzahlen, Fußnoten, Paginierung usw. zu trennen. Durch die nichtlineare Organisation soll es dem Leser freigestellt werden, auf welchen Pfaden er sich durch das Dokument bewegt.

Zur Realisierung dieser Bemühungen wird das Dokument mit weiteren Informationen angereichert, die jedoch für den Leser unsichtbar bleiben. Dieser Gedanke reicht zurück bis in die Anfänge des Buchdrucks. Dort sind formatierungsorientierte Auszeichnungssymbole, etwa für Fettdruck oder Unterstreichung, seit jeher bekannt. Vor dem Aufkommen der what you see is what you get Textverarbeitungssysteme waren diese bildlichen Symbole die einzige Möglichkeit zur Kommunikation präsentationsorientierter Information an den Schriftsetzer und Drucker.
Jedem Schüler ist bereits ein weiteres Beispiel einer editoriellen Auszeichnungssprache bekannt: Die graphischen Korrekturzeichen der Deutschlehrer. Auch sie liefern Informationen über den Inhalt, die nicht Bestandteil des Dokuments sind.

Voraussetzung für die angestrebte Flexibilisierung der Struktur eines Textes ist eine -- wie auch immer geartete -- technische Unterstützung. Seit den 60er Jahren wurden hierfür die aufkommenden elektronischen Rechenanlagen herangezogen. Eine der ersten Aktivitäten hierzu ist das von Ted Nelson initiierte (inzwischen legendäre) Xanadu-Projekt.

Zunächst erforderte die maschinelle Verarbeitung die Überarbeitung des Auszeichnungssymbolvorrates. Dies wurde notwendig, da eingesetzte Technik keine Unterstützung der alt-hergebrachten graphischen Auszeichungssymbole bot.
In einem ersten Entwicklungsschritt wurden daher die vormalig bildhaften Zeichen durch textuelle Pendants ersetzt und verallgemeinert. Beispielsweise: Überschrift zur inhaltlichen Kennzeichnung einer entsprechenden Textzeile.
Mit diesem Schritt erfolgte auch der Übergang zur formatierungsunabhängigen Auszeichnung, die bewußt auf die Beschreibung des späteren visuellen Aussehens der Information zugunsten einer neutralen deskriptiven Beschreibung der Semantik verzichtete.

In den 60er und 70er Jahren werden verschiedene Weiterentwicklungen der generischen Auszeichnungssprachen betrieben; u.a. bei der IBM durch das Team um Goldfarb, Mosher und Loire. Sie stellen 1969 unter dem Namen Generalized Markup Language einen Sprachvorschlag zusammen, der in der Folgezeit durch IBM kommerziell vermarktet wird.

Aus den GML-Aktivitäten bei IBM entwickelt sich die internationale Standardisierungsbewegung der Standard GML (SGML).
Durch sie wird eine Sprache festgelegt, welche die Definition eigener Sprachen erlaubt; daher auch der Begriff Metasprache. SGML bietet somit keinen feststehenden problemspezifischen Sprachumfang an, sondern eine Menge verschiedenster struktureller Konstrukte zur Formulierung von Dokumentgrammatiken.
In der Praxis wird der Einsatz einer mit Hilfe von SGML definierten Sprache oftmals plakativ zum Einsatz von SGML verkürzt, obwohl diese Begrifflichkeit lediglich den Erstellungsprozeß der Grammatik bezeichnet.

Mittels SGML definiert Tim Berners-Lee Mitte der 80er Jahre eine eigene Sprache zur vereinfachten Formulierung von Dokumenten, die er HyperText Markup Language (HTML) nennt. Hauptbeweggrund seiner Aktivitäten ist der Versuch den Dokumentenaustausch am Europäischen Kernforschungszentrum CERN rechnergestützt zu vereinfachen.
Die Eingangs erwähnten zentralen Hypertextkonzepte finden sich bereits in seinem ersten Sprachvorschlag wieder. Zur technischen Realisierung der Verknüpfung zwischen den Dokumenten mittels Ankern und Links definiert er den Uniform Resource Locator (URL), eine global eindeutige Adresse für beliebige Inhalte.

Seine Aktivitäten in Genf bilden die Keimzelle des Web.

In der Folgezeit, insbesondere im Zuge der Kommerzialisierung des Word Wide Web, entstehen verschiedene Revisionen der ursprünglichen HTML. Einige der Erweiterungen werden durch die beiden großen Web Browser Hersteller Microsoft und Netscape proprietär vorgenommen, um ihre Position am Markt zu stärken.
In der Konsequenz entstehen während des oft apostrophierten browser war teilweise inkompatible HTML-Dialekte. (Man denke nur an die Tags: marquee (nur Microsoft Internet Explorer) oder layer (nur Netscape Navigator))
Darüberhinaus entwickelt sich HTML zunehmend von einer Präsentations-orientierten Auszeichnungssprache zu einer semantischen. Dies bedeutet: während HTML in der ersten Grundform zunächst überwiegend Elemente bot, durch die die Präsentation der Inhalte am Bildschirm festgelegt wurde (Beispiele: b für Fettdruck, u für Unterstreichungen oder i für Kursivschreibung), wurden später zunehmend semantische Elemente eingeführt. Durch sie wird die Bedeutung der ausgezeichneten Information ausgedrückt (Beispiele hierfür: acronym zur Kennzeichnung von Abkürzungen, address für Adressen oder strong zur besonderen Betonung einer Textpassage).

So wünschenswert die sukzessive Umgestaltung der HTML an die veränderten Bedürfnisse war, so aussichtslos waren die Bemühungen dennoch. Während bei den Präsentations-orientierten Elementen zunehmend Vollständigkeit hinsichtlich der Anwenderwünsche erzielt werden konnte, offenbaren sich die bisher erfolgten semantischen Erweiterungen als permanent inadäquat.
Letztlich war der Versuch, durch Standardisierung, semantische Erweiterungen in HTML einzubringen in doppelter Hinsicht zum Scheitern verurteilt:
1. birgt der Ansatz die Gefahr, die Elementmenge in unbekannte Größen zu erweitern
2. muß die Semantik jedes Tags definiert, abgestimmt und verabschiedet werden.

Aus diesen Gründen wurde seitens des W3C nach einer tragfähigeren Lösung gesucht. Unter Rückgriff auf die HTML-Wurzeln (als Anwendung der Metasprache SGML) wurde das Projekt SGML for the Web initiiert.
Der letztendlich verabschiedete Vorschlag zur eXtensible Markup Language (XML) bildet konzeptionell eine Untermenge der Sprachmöglichkeiten von SGML. Konsequenterweise ist jedes XML-Dokument auch ein gültiges SGML-Dokument.

Die Abweichung zu SGML wird besonders aus den Entwicklungszielen für XML deutlich:

  1. Einfache Nutzung im Internet.
    In Abkehr von den Hauptnutzung SGMLs als offline Dokumentationsformat wird die Untermengenbildung XML für die primäre Nutzung im Internet vorgenommen.
  2. Unterstützung eines breiten Anwendungsspektrums.
    Auch hier soll die Untermengenbildung das Einsatzspektrum über die Hauptnutzung SGMLs als Format der technischen Dokumentation hinaus befördern.
  3. SGML Kompatibilität.
    XML bildet eine echte Untermenge des ISO-Standards SGML, durch diesen Schritt kann jedes XML-Dokument auch als gültiges SGML-Dokument interpretiert und durch die entsprechenden SGML-Werkzeuge verarbeitet werden.
  4. Einfache Applikationsentwicklung.
    Die Untermengenbildung wird im Hinblick auf eine gegenüber SGML deutlich vereinfachte Entwicklung von XML verarbeitenden Applikationen vorgenommen.
  5. Minimierung optionaler Sprachmerkmale -- Idealerweise gleich Null.
    Auch dieses Ziel ist im Hinblick auf eine vereinfachte Applikationsentwicklung, aber auch eine einfachere Benutzbarkeit durch Menschen auf dem Wege der Komplexitätsreduktion zu interpretieren.
  6. Lesbarkeit.
    Das entstehende Textformat soll für Menschen und Maschinen gleichermaßen les- und verstehbar sein.
  7. Kompakte Spezifikation.
    Die erstehende XML-Spezifikation sollte deutlich weniger Umfang aufweisen als der SGML-Vorgängerstandard. Letztlich konnte die reine Seitenzahl von über 600 Seiten für die SGML-Spezifikation auf ungefähr 30 Seiten für XML reduziert werden.
  8. Formaler und präziser Sprachentwurf.
    Um die schnelle Akzeptanz seitens der Anwender zu forcieren erachteten die Mitglieder der XML-Arbeitsgruppe die schnelle Verfügbarkeit von XML-Werkzeugen für essentiell. Aus diesem Grunde sollte der XML-Sprachentwurf möglichst leicht und eindeutig in XML-Werkzeuge zu implementieren sein.
  9. Leichte Dokumenterstellung.
    Die Erstellung von korrekten XML-Dokumenten sollte idealerweise so einfach sein, daß hierfür keine speziellen Werkzeuge benötigt werden.
  10. Nicht notwendigerweise knappes Markup.
    Kompaktheit und Effizienz hinsichtlich des Volumens eines XML-Dokuments war zu keinem Zeitpunkt eines der Hauptentwicklungsziele. Auf der Basis des XML-Information Sets ist es jedoch möglich beliebig kompakte Binärformate identischer Mächtigkeit zur die in der XML-Spezifikation vorgestellten Textnotation zu definieren.

XML stellt jedoch keine echte semantische Auszeichnungssprache dar, da durch die Metasprache lediglich eine Möglichkeit zur Formulierung eigener Syntax gegeben ist. Die Bedeutung der Elemente bleibt jedoch unberücksichtigt, und kann mittels XML nicht ausgedrückt werden.

Tabelle  1: Einige chronologische Eckdaten
Tabelle 1: Einige chronologische Eckdaten
Jahr
Ereignis
1945
Vannevar Bush diskutiert in seinem Artikel As We May Think ein persönliches Informationssystem mit Kommunikationsmöglichkeiten und Zugriff auf Bücher, Tonaufnahmen, etc. unter dem Namen Memex.
1967
William Tunnicliffe (Chairman des Graphic Communications Association (GCA) Composition Committee) schlägt aus seinen Erfahrungen bei der wiederholten Erstellung von Telephonkatalogen (yellow pages) vor, häufig auftretende strukturelle Elemente zu standardisieren.
September 1967
William Tunnicliffe (Vorsitzender der Graphic Communication Association) spricht sich auf einer Konferenz des Printing Office der Regierung von Kanada für die Separierung von Inhalt und Format aus.
Ende der 1960er Jahre
Stanley Rice, ein New Yorker Schriftsetzer, schlägt editorial structure tags vor.
Der CGA-Direktor Norman Scharpf initiiert das Projekt GenCode.
1969
Charles Goldfarb, Edward Mosher und Raymond Lorie entwickeln bei der IBM die Generalized Markup Language (GML).
Anwendungshintergrund war ein Projekt zur Integration von Informationssystemen für Anwaltskanzleien.
1970
Goldfarb formuliert zwei Grundprinzipien generalisierter Auszeichungssprachen:
1) Auszeichnungssprachen beschreiben die Dokumentstruktur, nicht die physischen Charakteristika wie Präsentation
2) Die Struktur der Auszeichnungssprache soll so gewählt sein, daß sie sowohl von Menschen als auch Maschinen interpretiert werden kann
1978
ANSI ruft Computer Languages for the Processing of Text-Komitee ins Leben.
Ziel ist die Weiterentwicklung der GML zu einem nationalen US-Standard.
1980
  • ANSI veröffentlicht ersten Entwurf einer standardisierten GML (SGML).
  • Tim Berners-Lee tritt seine Arbeit am Europäischen Kernforschungszentrum CERN an.
    Dort entwickelt er in der Folgezeit die (niemals veröffentlichte) Hypertextanwendung Enquire.
1983
Der International Revenue Service (IRS) und das US Verteidigungsministerium (DoD) übernehmen den sechsten Entwurf zur SGML (auch bekannt als GCA 101-1983).
1984
Die SGML-Arbeitsgruppe nimmt unter Schirmherrschaft der International Standardization Organization (ISO) als ISO/IEC JTCI/SC18/WG8 ihre Arbeit auf.
Goldfarb dient als technical leader der ISO-Gruppe, sowie dem umorganisierten ANSI-Komitee X3V1.8.
1985
Norm-Entwurf zu SGML veröffentlicht.
15. Oktober 1986
ISO verabschiedet SGML als ISO 8879:1986.
März 1989
Berners-Lee schlägt mit dem Dokument Information Management: A Proposal ein SGML-basiertes Hypertext-System zum Informationsaustausch vor.
1990
Am Weihnachtstag nimmt das World Wide Web seinen Betrieb mit zwei Maschinen am CERN auf.
Die notwendigen Implementierungen von HTML, HTTP und URL erfolgten durch Berners-Lee. Die erste WWW-Verbindung wird zwischen Berners-Lees Workstation und Robert Cailliaus' NeXT-Rechner aufgebaut.
Ein Screenshot des ersten Web-Browsers
NeXTStep-Implementierung des Browsers
1991
Beginn der turnusmäßigen Überarbeitungsphase von ISO 8879.
3. November 1992
Erster Entwurf zu HTML
Juni 1993
Einreichung des ersten HTML Entwurfs bei IETF.
Oktober 1994
14. November 1996
14. Januar 1997
Verabschiedung der HTML v3.2
1998
W3C gibt die erste Version von XML als Recommendation frei.
2000
  • W3C gibt XHTML v1.0 -- die Reformulierung von HTML v4.01 zu einer XML-Anwendung -- frei.
  • W3C verabschiedet XML 2nd edition; sie integriert u.a. die XML Namespaces und behebt einige editorielle Fehler.
2. Mai 2001
Das W3C verabschiedet den XML Schema-Standard.
Er geht an vielen Stellen deutlich über die ererbten SGML-Möglichkeiten hinaus, und markiert den Übergang von Präsentations-orientierten Strukturen hin zu Datenstrukturen.


Zum Abschluß dieser Einführung seinen die zehn Punkte zusammengestellt und kommentiert, die durch das World Wide Web Consortium als plakative Kurzcharakterisierung von XML veröffentlicht wurden:

  1. XML steht für strukturierte Daten.
    Diese Aussage betont die Rolle von XML als Sprache um Sprachen zu erzeugen. Nicht XML wird innerhalb verschiedenster Applikationen direkt verarbeitet, sondern XML basierte Formate. So steht nicht die XML selbst für all diese Anwendungsdomänen, sondern die jeweiligen problemspezifischen XML-basierten Sprachen. XML selbst dient lediglich der Strukturierung der verschiedensten darzustellenden Daten.
    Gleichzeitig rückt durch Aussage die Rolle der XML als Datenformat in den Vordergrund und läßt so die Weiterentwicklung gegenüber den präsentationsorientierten Vorläufern deutlich werden.
    Die Vorlesungskapitel Strukturelle Grundkonzepte, Dokument-Typ-Definitionen sowie XML Schemasprachen vermitteln einen Eindruck dieses Wandels und dokumentieren die Grundlagen des gegenwärtigen datenorientierten Einsatzes der XML.
  2. XML sieht ein wenig wie HTML aus.
    Diese Aussage soll offenkundig einerseits den bisherigen HTML-verwendenden Web-Autoren den Einstieg in die XML schmackhaft werden lassen. Dennoch führt sie ein wenig von der Grundidee XMLs als generischer Auszeichnungssprache für beliebigste Anwendungen weg, indem sie den Blick auf HTML focussiert.
    Die -- im Grunde der Verwandschaft zu SGML geschuldete -- offensichtliche syntaktische Ähnlichkeit zu HTML wird bereits bei der Betrachtung der strukturellen Grundkonzepte deutlich.
  3. XML ist Text, aber nicht zum Lesen.
    XML-Dokumente können sicherlich im wörtlichen Sinne „gelesen“ werden ... Die Aussage zielt jedoch auf den intendierten Einsatzzweck von XML: der Darstellung von Daten für den Austausch zwischen Maschinen. Unbenommen dessen kann XML selbstverständlich auch von Menschen gelesen und verstanden werden, wenngleich dies bei umfangreicheren XML-Dokumenten durchaus mühsam werden kann.
    Aufschluß über die textuelle Natur XMLs, insbesondere im Hinblick auf die Verwendung unterschiedlicher Alphabete, liefert das Kapitel strukturelle Grundkonzepte.
  4. XML ist vom Design her ausführlich.
    Hiermit wird versucht dem häufig geäußerten Kritikpunkt der Platzzunahme XML-codierter Inhalte gegenüber klassischen Darstellungsweisen etwas pauschal entkräftend entgegenzutreten. Sicherlich geht das W3C in dieser Aussage nicht fehl, wenn die Entwicklung der Netzwerkbandbreiten, der CPU-Leistung und der Speicherkapazitäten berücksichtigt. Andererseits ist die Aufblähung der XML-formatierten Inhalte im Vergleich zu optimierten Binärformaten nicht von der Hand zu weisen, wird jedoch durch die mit der Verwendung von XML einhergehenden Vorteile mehr als ausgeglichen.
    Einen ersten Eindruck der Natur XML-codierter Inhalte liefert das Kapitel strukturelle Grundkonzepte. Dort finden sich auch Ansätze die bekannte XML-Syntax kompaktifiziert darzustellen ohne die Vorteile der generischen Auszeichnungssprache aufgeben zu müssen.
  5. XML ist eine Familie von Techniken.
    Eine Aussage, die durch alle drei Kapitel der Vorlesung unterstrichen wird, die deutlich zeigen, daß XML nicht als isolierte Idee oder Technik anzusehen ist -- sondern erst im Zusammenspiel mit anderen XML-Standards und eingebettet in Applikationen und Infrastrukturen -- seine volle Wirkungsmächtigkeit entfalten kann.
  6. XML ist neu, aber nicht so neu.
    Diese Bezugnahme soll nochmals unterstreichen, daß XML keineswegs den Anspruch erhebt eine vollkommen neue technische Errungenschaft zu sein, sondern vielfach bekanntes und erprobtes aus der Informatik wiederverwendet und im neuen Verwendungskontext weiterentwickelt.
    Diese Aussage wird durch die in den einzelnen Kapiteln dargebotenen Rückbezüge auf bereits bekannte Techniken und Lösungsformen untermauert.
  7. XML überführt HTML in XHTML.
    Diese Aussage greift nochmals die Beziehung zwischen XML und HTML auf. Diesmal soll die Rolle von XML im Bezug auf die Weiterentwicklung von HTML zum XML-basierten Vokabular XHTML unterstrichen werden. So löst XML die Abhängigkeit zwischen SGML und HTML auf und reformuliert HTML auf der Basis von XML.
    Das Kapitel XHTML führt kurz in die Entwicklung der neuen HTML-Varianten auf Basis der XML ein und skizziert die vorgenommen Änderungen und zukünftige Erweiterungen dieser Hypertextsprache.
  8. XML ist modular.
    Hierdurch wird unterstrichen, daß XML kein in sich geschlossenes monolithisches Gebilde darstellt, sondern einzelne Vertreter aus der Familie der XML-Sprachen wahlfrei zur Lösung konkreter Probleme herangezogen werden können. Ebenso wird die Sprachfamilie beständig an verschiedensten Stellen unabhängig voneinander weiterentwickelt, ohne einer zentralen Koordination zu bedürfen.
    Einen Eindruck dieser Modularität liefern bereits die Grundlagensprachen des ersten Kapitels. Eindrucksvoll verstärkt wird diese Aussage durch die im zweiten Kapitel eingeführten problemorientierten Sprachen.
  9. XML ist die Basis für RDF und das Semantic Web.
    Grundidee des Semantic Web ist die Weiterentwicklung des sichtbaren XHTML-basierten Webs unter Nutzung seiner datenorientierten Ergänzung XML zu einem Netz von Sinnzusammenhängen. Die technische Voraussetzung hierzu bildet das im gleichnamigen Kapitel beschriebene Resource Description Framework welches eine XML-Sprache zur Darstellung von beschreibenden Daten zu beliebigen Quellen definiert.
  10. XML ist lizenzfrei, plattform- und herstellerunabhängig, und gut unterstützt.
    XML ist eine durch das World Wide Web Consortium herausgegebene Spezifikation, die kostenfrei über das Web bezogen werden kann und durch Interessierte ohne weitere Lizenzkosten in eigenen kommerziellen Produkten verwendet werden. Durch den Standardisierungsprozeß innerhalb des World Wide Web Consortiums wird sichergestellt, daß keine Ausführungsplattform bevorzugt wird und gleichzeitig keine Nachteile für Andere entstehen. Dies wird durch die herstellerunabhängige Organisation des Gremiums versucht zu garantieren, in dem zwar Hersteller Mitglied werden können, die technischen Entscheidungen jedoch Arbeitsgruppen obliegen, die nicht durch eine Firma dominiert werden können.
Web-Referenzen 1: Vertiefende Informationen
Web-Referenzen 1: Vertiefende Informationen


Web-Referenzen 2: Weiterführende Links
Web-Referenzen 2: Weiterführende Links


Die Rolle des World Wide Web Consortiums:
Das World Wide Web Consortium (W3C) stellt keine Normierungsorganisation im klassischen Sinne staatlicher Standardisierung wie die ISO, mit ihren nationalen Organisationen wie dem DIN, die UN, die ITU (früher CCITT) oder die IEC dar. Dies äußert sich schon darin, daß es keine normativen Dokumente verabschiedet, sondern lediglich Einsatzempfehlungen recommendations (im Sinne des IETF RFC 2119) gibt. Konkret bedeutet dies: Das W3C ist de jure nicht in der Lage auf rechtlichem Wege einklagbare Normen zu setzen. Vielmehr spricht es Empfehlungen aus, von denen unter bestimmten Umständen durchaus abgewichen werden kann. Jedoch empfiehlt RFC 2119 zunächst die Auswirkungen zu untersuchen und die endgültige Entscheidung gründlich abzuwägen.

Organisatorisch ist das W3C seit seiner Gründung 1994 ein Projekt des Massachusetts Institute of Technology (Labaratory for Computer Science) in Zusammenarbeit mit CERN, der Kejo Universität in Japan und dem European Research Consortium for Informatics and Mathematics (ERCIM). Unterstützt wird das Projekt durch DARPA und die Europäische Kommission.
Das W3C versteht sich als offenes herstellerunabhängiges Gremium. Zugang zu den Ergebnissen erhält jeder Interessierte kostenfrei über die W3C-Web-Site.
Die Mitwirkung an neuen Standards ist auf die Mitglieder des W3C beschränkt. Dieser Status ist juristischen Personen vorbehalten, steht aber generell jeder Institution oder jedem Unternehmen offen. Durch die Mitgliedschaft wird ein Sitz im Advisory Committee, dem offiziellen Bindeglied zwischen Mitgliedern und W3C-Team, erworben. Darüberhinaus kann jedes W3C-Mitglied an den laufenden Standardisierungsaktivitäten teilnehmen.

Das W3C veröffentlicht sechs verschiedene Typen von Dokumenten, wobei jedoch nur fünf formal zum Standardisierungsprozeß zu zählen sind.

Zustandsübergänge innerhalb des W3C-Standardisierungsprozesses
Web-Referenzen 1: Weiterführende Links
Web-Referenzen 3: Weiterführende Links
Informationen über das W3C
Liste der W3C-Mitglieder
Deutsches W3C-Büro
W3C Process Document; es definiert die verschiedenen W3C-Standardisierungsstatus


Definition 1: XML-Sprache
Definition 1: XML-Sprache
Eine Anwendung der Extensible Markup Language. Ein Vokabular, das aus Symbolen und der ihnen zugewiesenen Bedeutung (Semantik) gebildet wird, ergänzt um Regeln (grammatikalische Struktur und Gültigkeitsregeln für den Inhalt (z.B. Datentypen)) zur Kombination der Vokabularelemente.
Anwendungen einer so neu geschaffenen XML-Sprache L werden als XML-Dokumente, auch: L-Dokumente, bezeichnet.


Die XML-Sprachfamilie:

Familie der XML-Sprachen sowie weitere Standards

Die Graphik stellt den Zusammenhang einiger Basistechniken der XML sowie verschiedene bekannte XML-Sprachen dar.

Die strukturelle Basis der Extensible Markup Language bilden heute der XML Information Set, welcher die zentralen Begriffe der XML Strukturprimitive definiert, gemeinsam mit dem Codierungsstandard (ISO/IEC 10646) des Unicode Konsortiums zur plattformunabhängigen Darstellung beliebiger Zeichensätze.
XML selbst wurde ursprünglich als eine Untermenge der ISO-Norm der Standard Generalized Markup Language (SGML) definiert. Daher „erbt“ XML auch den dort definierten Grammatikmechanismus, die sog. Document Type Definitions (DTD), welche eine zusätzliche Text-basierte Sprache zur Festlegung des Vokabulars einer XML-Sprache liefern.

Aufbauend auf dem grundlegenden XML-Standard des W3C führt die Graphik die XML Namespaces ein, welche zur Unterscheidung von gleichen Bezeichnernamen in verschiedenen Verarbeitungskontexten dienen.
Diese Erweiterung der XML gestattet es Anwendern ihre Element- und Attributnamen vollkommen frei festlegen zu können, ohne zukünftig, etwa bei der Syndikatisierung verschiedener Dokumente mit Namenskonflikten konfrontiert zu werden.

Durch die XML HyperText Markup Language (XHTML) wird der große und wichtige Bereich der präsentationsorientierten Auszeichnungssprachen vertreten. XHTML v1.0 stellte die Reformulierung der bekannten Web-Sprache HTML v4.01 ein, die als SGML-Sprache nicht mehr durch das W3C weiterentwickelt wird.

Am Rande sei noch auf die (auf der Abbildung nicht dargestellte) ISO-Norm DSSSL (sprich: Dißl) -- die Document Style Semantics and Specification Language -- hingewiesen. Sie erlaubt die Formulierung von Transformationsregeln, die beliebige SGML-Dokumente in ein präsentationsfähiges Format überführen. Hierzu ist ein generischer Prozessor notwendig, der als Eingabe das umzuformende SGML-Dokument und die Transformationsregeln akzeptiert.
Bekannte DSSSL-Implementierungen: James Clarks Jade, oder Seng.
Die mit DSSSL gesammelten Erfahrungen flossen in die Entwicklung der XML-Stylesheet und Transformationssprachen XSL-Formatting Objects und XSLT ein.

Ein zentraler Bestandteil des Hypertext-Gedankens ist die nichtlineare Navigierbarkeit. In Web-Dokumenten, die mit der Sprache HTML erstellt wurden, findet sich dies durch die bekannten Hyperlinks verwirklicht. Der darstellende Browser sorgt dafür, daß durch Mausklick auf den meistens farblich und durch Unterstreichung hervorgehobenen Link die hinterlegte Aktion ausgeführt wird; üblicherweise wird ein neues HTML-Dokument geladen.
Auch XML verfügt über einen solchen -- jedoch durch Verallgemeinerung ungleich mächtigeren -- Verknüpfungsmechanismus. Er beschränkt sich jedoch nicht nur auf visuelle Hyperlinks, sondern steht durch den W3C-Standard XLink für alle XML-Sprachen zur Verfügung. Dadurch erweitert sich das aus HTML bekannte System u.a. um mehrgliedrige Verweise, die auf eine Menge von Dokumenten verweisen sowie verschiedene Verhaltensmuster bei der Traversierung eines Links.

Während Hyperlinks zur direkten Referenzierung einzelner Elemente eines XML-Dokuments verwendet werden, lagert die Lokatorsprache XPath dies in eine eigene Sprache aus. Sie stellt den Kern einer Anfragesprache, zur Extraktion verschiedenster Informationen (Knotenmengen, Positionsangaben, Werte, etc.) aus einem XML-Dokument, dar.
Aufgrund des dadurch eröffneten Anwendungsgebietes finden sich Teile von XPath in der Transformationssprache XSLT wieder. Hier dienen sie zum Auffinden der zu transformierenden Dokumentstrukturen.
XSLT erlaubt die Generierung beliebiger Unicode-Ströme aus XML-Strukturen. Häufigstes Einsatzgebiet in der Praxis ist aber die Verwendung zur Umformung von XML-Dokumenten. Hierzu wird nicht die volle Mächtigkeit der Ausgabe beliebiger Texte genutzt, sondern es werden „lediglich“ XML-Dokumente erzeugt.
Für das Anwendungsgebiet freier Dokumentstrukturen, wie z.B. RTF, Postscript oder LaTeX werden durch das W3C die Formatting Objects entwickelt. Konzeptionell baut dieser Standard auf XSLT auf, und reichert dieses um notwendige Primitive zur Erzeugung der erwähnten Formate an.

Ausgehend von mit XPath beschaffenen Lokalisierungsmöglichkeiten innerhalb eines XML-Dokuments oder einer Menge von XML-Dokumenten ist es konzeptionell nur ein kleiner Schritt eine Anfragesprache zu definieren. Dies wird durch XQuery vollzogen. Dieser Sprachstandard definiert eine SQL-artige algebraische Anfragesprache. Für beide Sprachen existiert eine textuelle nicht-XML-konforme kompakte Syntax, die ihre Einbettung in existierende XML-Vokabulare gestattet.

Zur Unterscheidung zwischen XML-codierten Sprachen und anderen Ansätzen hinterlegt die Graphik der Abbildung 2 alle im folgenden behandelten Standards zu denen eine XML-Sprache existiert farblich.

Auch das Resource Description Framework (RDF) baut auf den durch die Namensräum-Spezifikation etablierten Grundlagen auf. RDF definiert eine XML-Sprache, die ausgehend von klassischer Prädikatenlogik die Formulierung und maschinelle Auswertung von Aussagen über Web Ressourcen (etwa Text- oder Bilddaten) gestattet.

Die Erschließung neuer Anwendungsfelder läßt die Unzulänglichkeiten der Dokument-Typ-Definition als Möglichkeit zur Formulierung von XML-Vokabularen offenkundig werden, unterstützt der DTD-Mechanismus doch weder ein hinreichend entwickeltes Typsystem noch gestattet er die angemessene Formulierung von Strukturen wie sie in XML-Dokumenten benötigt werden.
Aus diesem Grunde entwickelt die XML-Sprache XML Schema die Primitive der DTD in einem eigenständigen XML-Vokabular fort, welches neben erweiterten Strukturierungsmöglichkeiten auch ein umfangreiches Typsystem zur Verfügung stellt.

Als eine Anwendung der Schemasprache stellt die Abbildung die beiden Sprachen WSDL und SOAP vor, die im Umfeld der Web Services große Bedeutung erlangt haben.
Diese XML-Sprachen dienen der Beschreibung von Aufrufschnittstellen und -charakteristika von Funktionalitäten, die über Internetprotokolle zur Verfügung gestellt werden. Die Darstellung des eigentlichen Aufrufs, des Namens der aufzurufenden Funktion sowie der benötigten Übergabeparameter, kann ebenfalls XML-codiert erfolgen. Den bekanntesten Ansatz hierzu bildet das SOAP-Protokoll welches einen betriebsystem- und programmiersprachenunabhängigen Nachrichtenmechanismus definiert.

1.2   Strukturelle Grundkonzepte

Die grundlegende XML-Syntax ist in der namensgebenden W3C-Recommendation der Extensible Markup Language definiert. Die Semantik der Metasprache wird hingegen durch den W3C-Standard des XML Information Set festgelegt.
Diese Spezifikationen beinhalten die grundlegenden Definitionen hinsichtlich Terminologie und Beziehung der verschiedenen möglichen Elemente eines XML-Dokuments. Im vorliegenden Teilkapitel werden beide Sprachaspekte grundlegend eingeführt und ein erstes Verständnis der XML vermittelt. Dabei wird in Form von Ausblicken auf nachfolgende Abschnitte der Bogen zu Grammatikdefinitionssprachen und weiterführenden Konzepten wie Namensräumen gespannt.
Zum leichteren Verständnis sind die aus der offiziellen Spezifikationen entnommenen formalen Grammatikdefinitionen der EBNF-Notation durch vereinfachte graphische Strukturdarstellungen ergänzt.

Definition 2: XML Dokument
Definition 2: XML Dokument
Ein XML-Dokument ist ein Datenstrom (der nicht zwingend als Datei vorliegen muß), welcher den Strukturierungsprinzipien der eXtensible Markup Language genügt.


Definition 3: XML Information Set
Definition 3: XML Information Set
Die Spezifikation des XML Information Sets definiert die Semantik der Metasprache XML, d.h. ihre zentralen Begriffe.
Gleichzeitig setzt es diese Begriffe in Beziehung und definiert so syntaxunabhängig die Struktur eines XML-Dokumentes.


Ausgehend von der Allgemeinheit der Aussage aus Definition 1 folgt, daß der Infoset neben seinem theoretischen Wert als Semantikdefinition zur XML auch zur Formulierung der Datenstrukturen, welche innerhalb eines XML-Prozessors vorliegen müssen, um beliebige XML-Dokumente verarbeiten zu können, herangezogen werden kann.
Daher läßt sich ein XML-Prozessor definieren als:

Definition 4: XML-Prozessor
Definition 4: XML-Prozessor
Ein XML-Prozessor ist eine maschinelle Komponente (typischerweise: Software), die zum Lesen, Speichern und Verarbeiten eines XML-Dokuments eingesetzt wird.
Er erlaubt Zugriff auf den Inhalt und die Struktur des XML-Dokuments.


Die XML-Spezifikation faßt den XML-Prozessorbegriff etwas enger und beschränkt ihn lediglich auf Software-Module, die XML-Dokumente lesend verarbeiten. Konzeptionell spricht jedoch nichts gegen eine Umsetzung in Hardware, beispielsweise im Kontext eingebetter Systeme etc. (In XML-Spezifikation nachschlagen)
Ferner nimmt die XML-Spezifikation an, ein Prozessor operiere nicht eigenständig, sondern im integrierten Zusammenspiel mit einer Applikation.

Beispiel 1: Ein erstes XML-Dokument
Beispiel 1: Ein erstes XML-Dokument
(1)<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>
(2)<Vorlesung>
(3)   <Wahlfach/>
(4)   SS2003
(5)   <Titel beginn="2003-03-17T14:00:00+01:00">XML</Titel>
(6)   <Hochschule>Fachhochschule Furtwangen</Hochschule>
(7)   <Praktikum>Freiwilliger Übungsbetrieb</Praktikum>
(8)</Vorlesung>
Download des Beispiels


Das Beispiel zeigt ein erstes einfaches XML-Dokument, welches bereits die häufigst verwendeten Sprachelemente der XML versammelt.
Jedem XML-Dokument entspricht genau ein Information Set, der alle Informationselemente des Dokuments in Form einer Baumstruktur beinhaltet. Die nachfolgende Abbildung zeigt den Information Set des Beispiels in der Notation eines UML-Klassendiagramms. Dabei sind die einzelnen Knoten des Information Sets als Objekte (Klassensymbole mit unterstrichenem Klassennamen) und die Eigenschaften der Knoten als Attributwerte dargestellt.

Darstellung des Information Sets zu Beispiel 1 als UML-Klassendiagramm

Document Information Item

Jedes Information Set besteht genau aus einem Document Information Item. Dieses stellt den äußeren Rahmen des XML-Dokuments dar. Es beinhaltet dokumentbezogene Informationen, wie die verwendete XML-Version und das gewählte Codierungsschema innerhalb des Unicode-Systems.
Das Document Information Item enthält daher u.a. die Informationen des XML-Dokumentprologs in der erste Zeile jedes Dokuments. Das durch die öffnende Winkelklammer und ein Fragezeichen eingeleitete Konstrukt ist in der ersten Zeile des Beispiels 1 dargestellt. Innerhalb des Prologs findet sich die Zeichenkette xml, sowie die Bezeichner version und encoding. Beiden ist ein durch doppelte Hochkommata umschlossener Wert nachgestellt, 1.0 für version, bzw. ISO-8859-15 für encoding.
Beendet wird der Prolog wiederum durch ein Fragezeichen und die schließende Winkelklammer. Wird auf die Angabe des optionalen Prologs im Dokument verzichtet, so sind die daraus ableitbaren Angaben im Document Information Item nicht gesetzt.

Als weitere Eigenschaften verfügt jedes Document Information Item über eine geordnete Liste von Kindknoten. Darin ist genau ein Element Information Item enthalten, welches den Startknoten des XML-Dokuments verkörpert. Wegen seiner hervorgehobenen Bedeutung als Wurzel des Dokumentbaumes wird dieser Knoten auch als Document Element bezeichnet.
Zusätzlich kann die Liste Elemente vom Typ Processing Instruction Information Item enthalten. Sie dienen der Darstellung von Verarbeitungsanweisungen, die durch den XML-Prozessor interpretiert werden.
Im Kopfbereich vor Document Element plazierte XML-Kommentare werden durch Comment Information Items innerhalb der children-Liste dargestellt.
Verfügt das XML-Dokument über eine Dokumenttypdeklaration, so findet sich auch ein Document Type Declaration Information Item in der Liste.
Deklarierte Notationen werden in einer ungeordneten Menge als Notation Information Item dargestellt.

Zusammengefaßt enthält das Document Information Item folgende Informationen:

Wie auch im Beispieldokument, bildet die erste Zeile den sog. Prolog eines jeden XML-Dokuments (In XML-Spezifikation nachschlagen) . Die Angabe der Version ist zwingend und derzeit auf die Konstante 1.0 fixiert. Die aktuelle XML-Spezifikation sieht als gültige Belegung der Versionsangabe ausschließlich die Zeichenkette 1.0 vor. Zukünftigen Weiterentwicklungen ist es jedoch freigestellt auch andere Revisionskennungen zu vergeben.
encoding leitet das zweite Namen-Wert-Paar ein. Die Deklaration ist innerhalb des Prologs optional, und kann daher auch unterbleiben. Die Zeichenkette der Encodingdeklaration benennt das Codierungsschema, welches für das so gekennzeichnete Dokument verwendet wurde. Es definiert den Satz der innerhalb des Dokumentes zugelassenen Zeichen fest.
Gemäß Produktion 22 der XML-Syntaxdefinition ist der gesamte Prolog optional.

Die Encoding-Deklaration hat folgendes Aussehen (In XML-Spezifikation nachschlagen) :

[80]EncodingDecl::=S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )
[81]EncName::=[A-Za-z] ([A-Za-z0-9._] | '-')*
[3]S::=(#x20 | #x9 | #xD | #xA)+
[25]Eq::=S? '=' S?

Die Festlegung der Produktion 80, sowie die der Produktion 23, stellt heraus, daß sich die Encodingdeklaration nicht auf die Prologzeile selbst auswirkt. Hier sind die beiden Zeichenketten xml und encoding in der Codierung UTF-8 oder UTF-16 Vorschrift.

Als Belegungen des Encoding Namens (EncName) sind beliebige Zeichensätze zugelassen. Der XML-Standard empfiehlt jedoch lediglich auf die durch die Internet Assigned Numbers Authority verwalteten zurückzugreifen (Dokument: Official Names for Character Sets) (In XML-Spezifikation nachschlagen) .
Die häufigsten praktisch eingesetzten Deklarationen sind die der ISO-8859 (extended ASCII)-Familie, sowie die der Unicode- und ISO-10646-Standards.
Die verschiedenen Abschnitte der ISO-8859 Familie werden als ISO-8851-n ausgedrückt, wobei n die Nummer des Abschnittes des zugehörigen ISO-Dokuments referenziert. Ferner können die durch JIS X-0208-1997 normierten asiatischen Zeichensätze als ISO-2022-JP, Shift_JIS und EUC-JP dargestellt werden.

Das Beispiel als japanisches XML-Dokument

Unicode stellt einen Industriestandard (entwickelt u.a. durch Apple, HP, IBM, Microsoft und SUN) zur Darstellung verschiedenster Alphabete und graphischer Zeichen dar. Sein zunächst durch 16-Bit codierter Zeichenvorrat bot Raum für 65536 unterschiedliche Symbole.
Die seit 1991 laufenden Unicodebemühungen münden in die ISO-Norm zur Erweiterung des klassischen ASCII-Codes (ISO 646) als ISO-10646 Universal Multiple-Octet Coded Character Set (UCS). Seit 1996 sind beide Standards synchronisiert und werden abgestimmt vorangetrieben.
UCS definiert zwei aufeinander aufbauende Codierungen: UCS-2 (16 Bit Umfang) und UCS-4 (32 Bit). Der bisherige Unicode-Standard ist voll kompatibel zu UCS-2 und durch diesen darstellbar.

Tabelle  2: Verschiedene Codierungen des Zeichens "A"
Tabelle 2: Verschiedene Codierungen des Zeichens "A"
Codierung
Bitbreite
Binärdarstellung
Größe der Beispieldatei in Byte
(ohne Berücksichtigung des XML-Prologs)
Bemerkung zum Meßwert
UTF-7
>= 7
100 0001
263
(encoding="UTF-7")
Extended ASCII, Latin-1 (ISO-8859-1)
8
0100 0001
258
(encoding="ISO-8859-1")
UTF-8
>= 8
0100 0001
259
(encoding="UTF-8") keine Byte Order Mark
UCS-2, Unicode
16
0000 0000 0100 0001
516
(encoding="UCS-2") keine Byte Order Mark
UTF-16 (big endian)
>= 16
0000 0000 0100 0001
516
(encoding="UTF-16") keine Byte Order Mark
UCS-4
32
0000 0000 0000 0000 0000 0000 0100 0001
1032
(encoding="UTF-8") keine Byte Order Mark
UTF-32
>= 32
0000 0000 0000 0000 0000 0000 0100 0001
1032
(encoding="UTF-32") keine Byte Order Mark


Die Zeilenumbrüche wurden in allen Fällen durch die Kombination von Wagenrücklauf und Zeilenvorschub ausgedrückt.

Die Tabelle stellt einige Codierungen zur Darstellung des Zeichens A zusammen.
Auffallend ist der große Platzbedarf der UCS-2 und -4 Codierungen. Insbesondere bei den „klassischen“ ASCII-Symbolen werden hier (u.U. sehr viele) führende Nullbits erzeugt, die in der Konsequenz zu einer deutlichen Vergrößerung der Beispieldatei führen.
Daher wurde mit dem UCS Transformation Format (UTF) eine kompaktere Darstellung zum jeweiligen UCS-Set eingeführt. UTF-8 verwendet standardmäßig die ersten acht Bit zur Darstellung der bekannten ASCII-Zeichen

Anmerkung: Inzwischen existiert auch eine „UTF-32“ genannte 32-Bit Ausprägung, diese ist jedoch identisch zu UCS-4, mit Ausnahme daß durch UTF-32 „nur“ 221-Zeichen dargestellt werden können.
Die Dateigröße ist daher für das betrachtete Beispiel in dieser Darstellungsweise unverändert zu der des UCS-4-Encodings.

Der Größenunterschied zwischen der UTF-7 codierten Datei und der Latin-1 encodierten erklärt sich aus der Darstellung des Umlautes sowie des +-Zeichens, die beide nicht nicht im klassischen 7-Bit ASCII-Code enthalten ist. So wird Ü im Wort Übungsbetrieb des Beispieldokumentes durch die die Bytefolge 2B 41 4E 77 2D dargestellt, während alle übrigen Zeichen durch ein einzelnes Byte ausgedrückt werden können.
UTF-8 ist in der Lage sämtliche Standard-ASCII-Zeichen durch jeweils genau ein Byte auszudrücken, wiederum für den Umlaut muß auf die 16-Bit-Darstellung des UCS-2 zurückgegriffen werden. Daher erhöht sich hier die Dateigröße um ein Byte.
Erwartungsgemäß beträgt der Umfang des UCS-2 codierten Dokuments exakt das Doppelte des 8-Bit Äquivalents der Latin-1-Darstellung.
Dasselbe gilt für die UTF-16-Variante, die für das vorliegende Beispiel unterschiedslos zu UCS-4 verläuft, da keinerlei Zeichen aus UCS-4 im Dokument auftreten.

Die nachfolgende Tabelle stellt beispielhaft die Anwendung der UTF-8-Codierung zusammen:

Tabelle  3: UTF-8 Codierung
Tabelle 3: UTF-8 Codierung
Unicode-Bereich
Bitbelegung
U-00000000 - U-0000007F:
0xxxxxxx
U-00000080 - U-000007FF:
110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF:
1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF:
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF:
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF:
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx


Diese Mimik zeigt den Nachteil des UTF-n-Encodings deutlich: Die Darstellung nicht n-Bit darstellbarer Zeichen benötigt u.U. mehr Bitstellen als im Standard UCS-Code.
So wird beispielsweise das Zeichen mit der größtmöglichen Position (7FFFFFFF) in UTF durch sechs Byte encodiert, während UCS dieselbe Information mit den verfügbaren 32-Bit ausdrücken kann. Andererseits „verschwendet“ die UCS-Darstellung für die niederwertigen Zeichen Bitstellen durch die führenden Nullen.

In der Praxis gilt es daher für das zu wählende Encoding einen möglichst guten Kompromiß zu finden: Im allgemeinen stellt das UTF-8-Encoding einen solchen dar, soweit überwiegend ASCII-Zeichen, und nur vereinzelt Sonderzeichen (hierzu zählen auch die deutschen Umlaute) eingesetzt werden.
Bei überwiegender Verwendung nicht in acht-Bit ASCII darstellbarer Zeichen (z.B. arabischer, chinesischer, etc.) erhöht die dann aufwendigere UTF-8-Codierung die Datenmenge.
So umfaßt die UTF-16-Darstellung des unten abgebildeten Beispieldokuments, welche in diesem Anwendungsfall identisch zu UCS-2 ist, 966 Bytes, während UTF-8 1299 Byte benötigt.

Ein XML-Dokument mit arabischen Zeichen

Achtung: Bereits durch die Unterstützung der beiden ISO-Zeichendarstellungen UTF-8 und UTF-16 ist die Konformität zum XML-Standard erfüllt! XML-Prozessorimplementierungen wird nicht abverlangt darüberhinausgehend weitere Darstellungen umzusetzen. (In XML-Spezifikation nachschlagen)

Wie bereits eingangs angemerkt, erklärt die XML-Spezifikation die Encodingdeklaration sowie den gesamten Prolog-Ausdruck als optionales Element (In XML-Spezifikation nachschlagen) .
Als Konsequenz geht dabei (auch) die Angabe des gewählten Encodings verloren.
Daher fordert der Anhang F der XML-Spezifikation Autodetection of Character Encodings bei einem von UTF-8 oder -16 abweichendem Codierungsschema die zwingende Angabe der XML-Deklaration (<?xml ...) (In XML-Spezifikation nachschlagen) .
Hintergrund dieser Maßnahme ist der Versuch anhand der damit bekannten fünf Zeichen das zugrundeliegende Encoding zu ermitteln.
Diese fünf Zeichen können als stabil angenommen werden, da Produktion 23 und 80 diese explizit von einem von UTF-8 oder -16 abweichenden Encoding ausnehmen.

Für Dokumente im deutschen Sprachraum, d.h. XML-Ströme die häuptsächlich aus den um die deutschen Umlaute ergänzten Standard-ASCII-Zeichen bestehen, hat es sich in der Vergangenheit eingebürgert den Zeichensatz latin-1 (ISO-8859-1) zu verwenden, um die Mehrbytedarstellung der Umlaute und weiterer Sonderzeichen in der UTF-Codierung zu umgehen.
Jedoch enthält der latin-1-Zeichensatz nicht das unter Unicode-Zeichennummer 20AC abgelegte Eurosymbol (_) welches zur Abkürzung des Währungsbegriffes der europäischen Gemeinschaftswährung verwendet wird.
Dieses Symbol wurde in die unter Nummer 15 veröffentlichte aktualisierte Fassung der Zeichensatzfamilie 8859 aufgenommen. Daher sollte bei der Erstellung von XML-Dokumenten generell darauf geachtet werden entweder ISO-8859-15 als Codierung zu wählen oder auf die ohnehin ungleich flexiblere UTF-Codierung zurückzugreifen.

Die Darstellung der Abbildung 6 faßt die syntaktischen Elemente abgekürzt zusammen:

Struktur eines XML-Dokuments
Web-Referenzen 1: Weiterführende Links
Web-Referenzen 4: Weiterführende Links
•Payer, M.: UNICODE, ISO/IEC 10646, UCS, UTF
•Kuhn, M.: UTF-8 and Unicode FAQ
SC Unipad ein kostenfreier Unicode Editor


Element Information Item

Jedes XML-Dokument enthält mindestens ein Element, das Document Element.
Seine, wie auch die Grenzen aller anderen Elemente, werden durch die Start- und Ende-Marke (engl. Tag) markiert. Für den Sonderfall eines leeren Elements bildet die Start- auch zugleich die Ende-Marke. Als eine Konsequenz können diese Elemente keine weiteren Kindknoten besitzen.

Die XML-Spezifikation legt den Aufbau des Start-Tags wie folgt fest (In XML-Spezifikation nachschlagen) :

[40]STag::='<' Name (S Attribute)* S? '>'
[41]Attribute::=Name Eq AttValue

Mittels der Tag-Namen werden die Typen eines Dokumentes definiert. Sie werden später, in Verbindung mit einem Grammatikmechanismus wie DTD oder XML-Schema, zur Gültigkeitsprüfung herangezogen.
Der Aufbau der Elementnamen ist ähnlich zu den aus den Programmiersprachen bekannten Regeln. Am Beginn muß ein Buchstabe, ein Unterstrich oder der Doppelpunkt stehen. Darauf können nahezu beliebige Zeichen folgen, die über ihre Unicoderepräsentation genau definiert sind.
Leerzeichen und sog. white spaces (vgl. Produktion 3 der XML-Spezifikation) wie Tabulatoren und Zeilenvorschübe sind nicht zugelassen. Desweiteren darf ein Elementname weder Auszeichnungssymbole, wie die öffnenden und schließenden Winkelklammern, enthalten, noch mit der Zeichenkette XML beginnen. Die Zeichenfolge XML ist -- in allen Schreibweisen -- für die Standardisierung reserviert und wird ausschließlich in W3C-Dokumenten verwendet.
Durch den Namespace Standard (siehe Abschnitt 1.3) wird dem Doppelpunkt, als Trennsymbol zwischen Namensraumkürzel und Elementnamen, eine besondere semantische Bedeutung zugeschrieben. Daher sollte -- obwohl er spezifikationsgemäß ein erlaubtes Zeichen darstellt -- von seiner Verwendung in Elementnamen abgesehen werden.

Oftmals wird -- insbesondere in der Praxis -- die existierende und notwendige Unterscheidung zwischen Tag und Element nicht getroffen.
Die Tags oder Marken drücken beschreibende Information über ein Element aus. Der durch den Tag ausgedrückte Elementname liefert somit lediglich deskriptive Information über die Natur des Elements. Hierzu können Worte einer natürlichen Sprache verwendet werden, jedoch auch beliebige andere identifizierende Zeichenketten. Üblicherweise sind jedoch sprechende Tags anzutreffen.

Über den Tag-Namen hinaus kann ein Startelement auch noch Attribute enthalten (Vgl. Produktion 41). Diese sind jedoch nicht vom Typ Element und werden daher im Abschnitt Attribute Information Item betrachtet.

Der Aufbau eines Elementnamens wird durch die Produktionen 4ff definiert (In XML-Spezifikation nachschlagen) :

[4]NameChar::=Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
[5]Name::=(Letter | '_' | ':') (NameChar)*
[6]Names::=Name (S Name)*
[7]Nmtoken::=(NameChar)+
[8]Nmtokens::=Nmtoken (S Nmtoken)*

Im Beispiel sind Vorlesung, Titel und Hochschule („normale“) Elemente, während ein leeres Element darstellt.
Die Abbildung zeigt, daß auf der semantischen Ebene des Information Sets die syntaktische Unterscheidung zwischen Elementknoten mit Kindelementen und leeren Elementen des XML-Dokuments keine Berücksichtigung findet.

Eine Sonderstellung unter den Elementen eines Dokuments nimmt der ausgezeichnete Wurzelknoten ein, er wird auch durch das Document Information Item referenziert. Unterhalb dieses Knotens spannt sich der Dokumentbaum auf. Hierfür enthält jedes Element Information Item eine geordnete Menge (children) weiterer Elementknoten.
Die durch den Elementnamen verwirklichte Typisierung spiegelt sich im Information Set durch das Attribut local name wieder.

Darüberhinaus enthält jedes Element Information Item durch die Eigenschaft namespace name die Identifikation des Namensraumes, in dem dieses Element plaziert ist.
Das Namensraumkürzel, welches zur Identifikation eines Elements herangezogen wird, findet sich in der Eigenschaft prefix.
Der local name entspricht dem -- um Namensraumkürzel und trennenden Doppelpunkt gekürzten -- wiedergegebenen Elementnamen des XML-Dokuments.
Zusätzlich wird jeder Namensraum, der syntaktisch an die Attributdefinition angelehnt ist, in ein Element der ungeordneten Menge namespace attributes abgebildet, welche (nochmals) die Namensräume eines Elements beinhaltet.

Beispiel 2: Element mit deklariertem Namensraum
Beispiel 2: Element mit deklariertem Namensraum
(1)...
(2)	<myNS:aParent xmlns:myNS="example.com">
(3)		<myNS:aElement/>
(4)	</myNS:aParent>
(5)...


Das Beispiel zeigt das leere Element aElement innerhalb des Elements aParent. Durch das Elternelement wird der Namensraum example.com deklariert und dem Kürzel myNS zugewiesen.
Gemäß den Prinzipien der Namensräume steht der auf dem Elternknoten deklarierte Namensraum auch in allen Kindknoten zur Verfügung. Daher enthält die Eigenschaft in-scope namespaces des Elements aElement auch die Namensräume der übergeordneten Elemente.
Das resultierende Element Information Item des Knotens aElement ergibt sich daher als (der Ausschnitt enthält nur die für das Beispiel relevanten Elemente):

local name=aElement
namespace URI=example.com
prefix=myNS

Nähere Ausführungen zur Bedeutung von Namensräumen und ihrer Verwendung finden sich im Abschnitt Namensräume.

Verweise auf die im Dokumentbaum nachfolgenden Knoten eines Elements werden in einer geordneten Liste children gesammelt. Ihre Inhalte sind sind vom Typ Element Information Item, Unexpanded Entity Reference Information Item, Character Information Item und Comment Information Item.
Anhand der beiden Informationstypen Element Information Item und Character Information Item zeigen sich bereits die beiden Strukturierungsformen eines XML-Dokuments. Einerseits die durch die starke Verwendung von Elementen- und Attributen gekennzeichnete strukturierte Darstellung, andererseits die durch „eingestreuten“ Freitext entstehende charakteristische semistrukturierte Variante.
In beiden Fällen werden die textartigen Inhalte durch Character Information Items repräsentiert.
Das Beispiel zeigt die verschiedenen Auftretensformen exemplarisch. Der Inhalt der Elemente title und organization ist rein Zeichenketten-artig; jedoch mischt vorlesung strukturierten Inhalt (in Form der genannten Elemente) und unstrukturierte Information -- repräsentiert durch den Text 2002/03.
Die XML-Spezifikation prägt für Zeichenketten-artige Inhalte, die optional durch eingestreute Elemente angereichert werden, den Begriff mixed Content.

children enthält jedoch keine Verweise auf die Attribute eines Elements. Diese sind durch die separate ungeordnete Menge attributes repräsentiert. Die Diskussion der als Attribute Information Item bezeichneten Mengenelemente findet sich im folgenden.

Die in der Abbildung dargestellte Beziehung parent verbindet jedes Element mit seinem übergeordneten. Als Ziele dieser Referenz sind ausschließlich Ausprägungen von Document Information Item oder Element Information Item zugelassen.
Diese Festlegung untermauert nochmals die strikte Baumstruktur eines XML-Dokuments. Andernfalls müßte parent als Menge definiert werden.

Attribute Information Item

Das betrachtete Beispiel enthält, neben den Elementen, auch ein XML-Attribut.
Syntaktisch werden Attribute innerhalb eines Start-Tags plaziert und durch Namen-Wert-Paare ausgedrückt (In XML-Spezifikation nachschlagen) .

Der Information Set enthält folgende Eigenschaften zu jedem Attribut:

Im Vergleich zum Element Information Item erlaubt das Attribut keine weitere Unterstrukturierung (im XML-Sinne); insbesondere fehlen mengenwertige Eigenschaften zur Aufnahme der dann notwendigen Verweise. Stattdessen wird der gesamte Inhalt durch die Eigenschaft normalized value dargestellt.
Daher dürfen innerhalb von Attributen keine (Meta-)Symbole wie die öffnende Winkelklammer auftreten, die als Starttags (miß-)interpretiert werden könnten (In XML-Spezifikation nachschlagen) .

Auch die Form des Auftretens von Attributen innerhalb des definierenden Elements unterscheidet sich von der der Subelemente innerhalb eines Elements. Während Kindelemente durch die geordnete Liste children dargestellt werden, können Attribute (formalisiert in der ungeordneten Menge attributes) in beliebiger Reihenfolge angegeben werden, ohne die Dokumentsemantik zu verändern. Mehr noch, die Listenkonstruktion erlaubt das unterscheidbare mehrfache Auftreten desselben Elements. Diese Mimik ist für allgemeine Mengen, und damit für Attribute, nicht möglich.

Element vs. Attribut
Der Vergleich der Eigenschaften von Element und Attribut zeigt bereits, daß sich nicht weiter strukturierte Elemente auch durch Attribute darstellen ließen. Dies wirft innerhalb der Betrachtung der Syntax eines XML-Dokuments bereits die Frage nach der Organisation, und damit dem Entwurf, eines solchen auf.
Die bestehende XML-Spezifikation bleibt jedoch eine Anwendungs- oder Einsatzempfehlung zu dieser Fragestellung schuldig.
Aufgrund der inhärenten Einschränkungen der Attributprimitive bietet sich ihr Einsatz nur in einigen Sonderfällen an. Beispielsweise zur Darstellung deskriptiver Information über das enthaltende Element, die nicht Bestandteil der im XML-Dokument dargestellten Information ist. Hierbei kann es sich um Informationen höherer Ordnung, sog. Metainformation handeln.

Generell bieten sich Elemente immer dann an, wenn eine weitere Unterstrukturierung des Inhaltes gewünscht oder vielleicht zukünftig notwendig ist. Die Darstellungsform als Attribut würde in diesem Fall eine strukturelle Umorganisation des XML-Vokabulars erfordern, da die Spezifikation keine Unterstrukturierungsmöglichkeit für Attribute vorsieht.
Darüberhinaus gestatten Attribute keine Wiederverwendung in verschiedenen Bedeutungskontexten, da sie syntaktisch an das umgebende Element gebunden sind. Diese Einschränkung wird zwar durch die Einführung des Standards XML Schema weitgehend gemildert, jedoch nicht die zuvor genannte Mächtigkeitseinschränkung. Zusätzlich stellen Attribute die einzige Möglichkeit zur Typisierung des Inhaltes dar solange DTDs verwendet werden. Dieser Punkt dürfte jedoch durch den wachsenden Praxiseinsatz der XML Schemata immer mehr an Bedeutung verlieren.

Die Darstellung der Abbildung 7 faßt die syntaktischen Elemente abgekürzt zusammen:

Struktur eines XML-Elements

Character Information Item

Die Betrachtung der Attribut- und Elementknotentypen im Information Set zeigt bereits die zwei grundlegenden Arten der Informationsdarstellung eines XML-Dokumentbaumes.
Die Eigenschaft normalized value des Attribute Information Items kapselt den im XML-Dokument angegebenen Inhalt direkt im Informationsknoten. Der Datentyp der Eigenschaft ist für alle Dokumenttypen fixiert angebbar, da keine weitere Unterstukturierung von Attributen erfolgen kann.
Entgegensetzt hierzu verläuft die Argumentationslinie für Elemente. Ihr Inhaltsmodell kann eine freie Mischung aus Zeichenketten-Daten und weiteren Elementen aufweisen. Die Länge der Zeichenketten ist hierbei nicht näher festgelegt. Daher können diese im minimalen Falle nur aus einem einzelnen Zeichen bestehen. (In XML-Spezifikation nachschlagen) .
Innerhalb des Information Sets eines Dokuments werden alle Zeichen im Rumpf eines Elements als Ausprägungen des Character Information Items dargestellt.

Jedes Character Information Item stellt das im Dokument gegebene Zeichen gemäß ISO 10646-Codierung in der Eigenschaft character code dar. Die Werte können hierbei jedoch nur in den durch die Spezifikation vorgegebenen Grenzen variieren (In XML-Spezifikation nachschlagen) . Darüberhinaus genügt bereits die Unterstützung der UTF-8 und -16-Darstellung zur Erfüllung der Spezifikationsanforderungen an konforme Prozessoren.
Handelt es sich bei dem betrachteten Zeichen um einen white-space (Leerzeichen, Tabulator, Zeilenvorschub, Wagenrücklauf), der in der DTD als „erhaltenswert“ spezifiziert wurde, so ist die Boole'sche Eigenschaft element content whitespace auf true gesetzt; andernfalls konstant auf false. Häufig werden white-spaces zur besseren visuellen Strukturierung des XML-Dokumentes eingesetzt. So enthält das Beispieldokument jeweils nach der schließenden Marke einen Zeilenvorschub. Unter Datengesichtspunkten handelt es sich hierbei jedoch um keine verwertbare Information. Die Angabe der Berücksichtigung bzw. Vernachlässigung im XML-Dokument existierender white-spaces kann in der DTD gesetzt werden. Ist keine solche Deklaration gesetzt oder existiert keine explizite Grammatik, so hat die Eigenschaft element content whitespace keinen Inhaltswert.
Der als parent-Eigenschaft realisierte Verweis auf das beherbergende Elternelement bildet den Abschluß der Eigenschaften des Character Information Items.
Im betrachteten Beispiel sind unterhalb der Elemente organization und title  Character Information Element-Ausprägungen plaziert. Die Darstellung zeigt diese als Objekte (Unterhalb des organization-Knotens wurde aus Übersichtlichkeitsgründen auf die Darstellung verzichtet).

Eine Sonderrolle kommt den Zeichen zu, die auch als Metasymbole der Auszeichnungssprache dienen. Sie dürfen daher nicht in XML-Dokumenten auftreten.
Bei diesen Zeichen handelt es sich um die beiden Winkelklammern, die einfachen und doppelten Anführungszeichen sowie das Kaufmanns-Und. Um eine Fehlinterpretation zu vermeiden existieren hierfür vordefinierte Textersetzungsmuster.
Jeder spezifikationskonforme XML-Prozessor berücksichtigt diese Symbole und gibt sie in der korrekten Darstellung an die Applikation weiter; damit sind diese Fluchtsymbole (engl. escape characters) aus Applikationssicht vollkommen transparent.

Tabelle  4: Vordefinierte Textersetzungsmuster
Tabelle 4: Vordefinierte Textersetzungsmuster
Entitätsreferenz
Ausgedrücktes Zeichen
&amp;
&
&lt;
<
&gt;
>
&apos;
'
&quot;
"


Web-Referenzen 2: Weiterführendes ... Die in XHTML v1.0 vordefinierten Entitäten
Web-Referenzen 5: Weiterführendes ... Die in XHTML v1.0 vordefinierten Entitäten


Comment Information Item

Zur Dokumentation steht innerhalb jedes XML-Dokuments die von SGML ererbte Kommentierungssyntax zur Verfügung.
Die Spezifikation erlaubt die Anbringung von Kommentaren an zwei Stellen im XML-Dokument:

Nicht erlaubt sind demnach Kommentare in Tags, d.h. innerhalb geöffneter Winkelklammern.
Dergleichen gilt für Kommentare selbst, was geschachtelte Kommentare verbietet.

Ferner können Kommentare desselben Stils auch in DTDs und im internal Subset verwendet werden.

Produktion 15 der XML-Spezifikation legt die Struktur wie folgt fest:

[15]Comment::='<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'

Als Konsequenz sind innerhalb von Kommentaren alle Zeichen, auch Metasprachensymbole, zugelassen. Somit ist das beliebige „auskommentieren“ von Dokumentteilen möglich.
Als zentrale Einschränkung dürfen (aus SGML-Kompatibilitätsgründen) keine zwei aufeinanderfolgenden Trennstriche (hyphen-minus, ISO 10646 #x2D) innerhalb eines Kommentars auftreten, da diese fehlerhafterweise als Beginn des Kommentarendes interpretiert würden.

Der gesamte Inhalt eines Kommentars wird als uninterpretierte Zeichenkette in der Eigenschaft content des Comment Information Items abgelegt.
Zusätzlich verweist jeder Kommentar über die bekannte parent-Eigenschaft auf seinen Elternknoten. Wie bereits durch die beiden Einsatzformen angedeutet, kann es sich hierbei ausschließlich um ein Document Information Item oder ein Element Information Item handeln.

Beispiel 3: Verschiedene Kommentarstrukturen
Beispiel 3: Verschiedene Kommentarstrukturen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<Root>
(3)	<!-- this is a comment -->
(4)	<ElementA>
(5)		<ElementB>
(6)			<!--
(7)			<ElementC/>
(8)			<ElementD att1="..."/>
(9)			-->
(10)		</ElementB>
(11)	</ElementA>
(12)</Root>


Das Beispiel zeigt verschiedene Einsätze von Kommentaren. Zunächst eine einzeilige Anmerkung, die nur verschiedene Zeichen versammelt. Im Anschluß einen mehrzeiligen Kommentar, der auch XML-Strukturen beinhaltet. Ein prozessierender Zugriff auf den Kommentarinhalt ist jedoch nicht vorgesehen, und wird durch gängige Parser und APIs zumeist nicht unterstützt.

Processing Instruction Information Item

Im Gegensatz zu den prinzipiell in beliebigem Freitext formulierbaren Kommentaren, die üblicherweise zur Kommunikation mit einem menschlichen Leser des XML-Dokuments dienen, zielt die Processing Instruction und das zugehörige Element des Information Sets auf Kommentare, welche einen maschinellen Verarbeiter des XML-Dokuments, den XML-Prozessor, betreffen.

Im Grunde genommen läuft die Anreicherung eines XML-Dokuments mit Verarbeitungsinformation der Idee einer deskriptiven Auszeichnungssprache entgegen ...
Jedoch wurde für die XML beschlossen, nicht zuletzt aus Kompatibilitätsgründen zu SGML, dieses Sprachmerkmal beizubehalten. Eine mögliche weitere Erklärung könnte das syntaktische Aussehen der XML-Deklaration innerhalb des des Dokumentprologs sein. Ihre in Produktion 23ff festgelegte Struktur stellt eine Anwendung der Processing Instruction dar, auch wenn dies innerhalb der Spezifikation nicht explizit formuliert wird.

Die Syntax einer Processing Instruction lautet:

[16]PI::='<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
[17]PITarget::=Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))

Eine Processing Instruction wird demnach immer durch eine öffnende Winkelklammer und ein folgendes Fragezeichen eingeleitet. Daran schließt sich die Benennung der Applikation an, für die diese Instruktion eingefügt wurde. Optional können weitere Zeichen -- ausgenommen der Kombination aus Fragezeichen und schließender Winkelklammer -- folgen.
Das adressierte System kann beliebig identifiziert werden, jedoch ist die Zeichenkette XML in allen Variationen ausgeschlossen.
Unbedachterweise verbietet die Spezifikation jedoch nicht die Bildung von Namen, die XML als Präfix nutzen ... Jedoch sollte von der Nutzung solcher Konstruktionen abgesehen werden, da sie zur Verwirrung der (menschlichen) Leser beitragen.

Wie Kommentare auch können Processing Instructions an beliebiger Stelle innerhalb des XML-Dokuments auftreten: Vor Beginn des Wurzelelements sowie im Rumpf jedes Elements. Nicht gestattet ist ihre Angabe in Elementnamen und Attributen.
Ergänzend sei angemerkt, daß die Angabe von Processing Instructions auch innerhalb der Document Type Definition erfolgen kann. (siehe Document Type Definition Information Item).

Beispiel 4: Verschiedene Processing Instructions
Beispiel 4: Verschiedene Processing Instructions
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<?mySystem value="42"?>
(3)<root>
(4)   <?System2?>
(5)   <elementA>
(6)     <?System3 a="1" anotherValue?>
(7)  </elementA>
(8)</root>
Download des Beispiels


Übung 1: Processing Instructions
Übung 1: Processing Instructions
Begründen Sie mit Hilfe der XML-Spezifikation warum Processing Instructions nicht innerhalb von Elementen und Attributen zugelassen sind.
Hinweis: Es gibt mehr als eine Begründung!


Das Processing Instruction Information Item enthält die angesprochene Zielapplikation als Namen innerhalb der Eigenschaft target.
Der weitere Inhalt der Deklaration wird uninterpretiert als Zeichenkette in die Eigenschaft content übernommen.
Neben einem Verweis auf die Basis-URI der Processing Instruction wird durch parent das Elternelement -- entweder ein Knoten des Typs Document Information Item oder Element Information Item -- referenziert.

Zur Formalisierung der Identifikation der Zielapplikation empfiehlt die XML-Spezifikation die Verwendung des Sprachmittels Notation.

Notation Information Item

Notationen können nicht in XML-Dokumenten auftreten, sondern sind DTDs vorbehalten.
Dennoch sollen sie hier wegen ihrer Berücksichtigung im Information Set und der Verbindung zu den Processing Instructions kurz eingeführt werden.

Durch Notations können Dateninhalten externe Quellen (etwa: URLs oder Applikationen) zugeordnet werden. Der Grundgedanke liegt in der Erweiterung der Ausdrucksmächtigkeit eines XML-Dokuments. Parser berücksichtigen solch typisierte Inhalte jedoch nicht. Die Behandlung muß (proprietär) in der datenverarbeitenden Applikation erfolgen.
Die Syntax der Notation lautet:

[82]NotationDecl::='<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
[83]PublicID::='PUBLIC' S PubidLiteral
[75]ExternalID::='SYSTEM' S SystemLiteral
   | 'PUBLIC' S PubidLiteral S SystemLiteral

Die einfachst denkbare Anwendung von Notations zielt auf Informationen, deren Inhalte nicht durch den XML-Prozessor auf syntaktische Korrektheit geprüft werden. Dies sog. unparsed entities werden aus einem eineindeutigen Namen und einer freien Zeichenkette gebildet.
Die Zeichenkette bezeichnet primär die als URI (gemäß RFC 2396 und 2732) codierte Identifikation des verarbeitenden Systems. Im Falle standardisierter Inhalte kann auf einen public identifier zurückgegriffen werden. Üblich ist die Verwendung von system identifiern, die auf eine bekannte URI oder ein installiertes Anwendungsprogramm verweisen.

Beispiel 5: NOTATIONS
Beispiel 5: NOTATIONS
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<!DOCTYPE someContent [
(3)<!NOTATION isoDate SYSTEM "http://www.iso.ch/markete/8601.pdf">
(4)<!NOTATION gif PUBLIC            
(5)    "-//Compuserve Information Services//NOTATION Graphics Interchange     
(6)        Format//EN">
(7)<!NOTATION hex SYSTEM "hexEditor.exe">
(8)<!ELEMENT someContent (#PCDATA)>
(9)<!ATTLIST someContent format NOTATION (hex) #IMPLIED> ]>
(10)<someContent format="hex">4C 65 74 20 61 6C 6C 20 68 6F 70 65 20 61 
(11)62 61 6E 64 6F 6E 2C 20 79 65 20 77 68 6F 20 6D 61 79 20 65 6E 74 
(12)65 72 20 68 65 72 65 21</someContent>
Download des Beispiels


Hinweis: Die Deklarationen in DTD-Syntax -- erkennbar am einleitenden Ausrufezeichen (!) -- sind kein XML! Sie müssen daher nicht den syntaktischen Konventionen der Extensible Markup Language genügen!

Im Beispiel wird nach der DOCTYPE-Deklaration DTD-Syntax verwendet, um das Inhaltsmodell des nachfolgenden XML-Dokuments festzulegen. Die genaue Bedeutung der DTD-Konstrukte wird im Abschnitt 1.4 behandelt.
Das Beispiel beinhaltet drei Notationselemente: isoDate, gif und hex. isoDate referenziert die internationale Norm 8601 als PDF-Dokument.
Die durch hex definierte NOTATION wird im XML-Dokument verwendet.
Diese Anwendung offenbart auch einen weiteren Aspekt dieses Konstrukts; die Nachbildung von Datentyp-ähnlichen Strukturen, die jedoch durch den Anwendungsprogrammierer umgesetzt werden müssen.
Im Vergleich der beiden SYSTEM-Referenzen zeigt sich die Allgemeinheit des URI-Mechanismus als Schwäche. Da anhand der URI nicht ermittelbar ist, ob es sich bei der identifizierten Lokation um ein Dokument, ein System oder ein ausführbares Programm handelt, läßt sich keine verbindliche Semantik zur Behandlung von NOTATION-Elementen angeben.
Die mit gif benannte Notation definiert einen Public-Identifier, der nicht auf eine URI verweist, sondern eine weltweit eindeutige Benennung darstellt. Die Abbildung auf eine Systemlokation zur Behandlung der Notation kann durch die zusätzliche Angabe eines System-Identifiers erfolgen. Liegt eine solche nicht vor, muß der XML-Prozessor für die Abbildung Sorge tragen.
Ein weiteres Beispiel für die Verwendung des NOTATION-Konstrukts findet sich im Zusammenspiel mit ungeprüften Entitäten.

Jedes NOTATION-Element wird im Information Set durch ein Notation Information Item repräsentiert. Es enthält neben dem Namen (Eigenschaft name) die beiden möglichen Identifierinhalte in den Eigenschaften system identifier bzw. public identifier. Beide Eigenschaften sind Zeichenketten-artig; lediglich die URI-spezifische Inhaltsnormalisierung wird (wie in der XML-Spezifikation beschrieben) durchgeführt.

Document Type Declaration Information Item

Dokumente, zu denen eine -- in der Sprache DTD formulierte -- explizite Grammatik existiert, verfügen über eine DOCTYPE-Deklaration, welche den durch URI identifizierten Ablageort der DTD enthält.
Die Charakteristika dieser Information sind im Document Type Declaration Information Item zusammengefaßt. Es enthält alle Informationen, die im XML-Dokument über die DTD vorliegen. Daher bietet es keinen Zugriff auf die durch die DTD festgelegte Grammatik!
Im Einzelnen bietet der Information Set Knotentyp:

Das Beispiel zeigt zwei DOCTYPE-Deklarationen. Zunächst eine SYSTEM-Deklaration, welche die Datei abc.dtd im aktuellen Dateisystemkatalog über eine URI referenziert.
Die zweite Deklaration zeigt die HTML v4.01-Standarddeklaration. Für sie existiert der dargestellte PUBLIC-Identifer. Zusätzlich wurde ein SYSTEM-Identifier (er folgt direkt ohne Schlüsselwort auf den PUBLIC-Identifer) angegeben, der, per URI, auf das DTD-Dokument beim W3C verweist.

Beispiel 6: Verschiedene DOCTYPE-Deklarationen
Beispiel 6: Verschiedene DOCTYPE-Deklarationen
(1)<!DOCTYPE someContent SYSTEM "abc.dtd"> 
(2)<!DOCTYPE HTML PUBLIC 
(3)	"-//W3C//DTD HTML 4.01//EN"    
(4)	"http://www.w3.org/TR/html4/strict.dtd"> 


Unexpanded Entity Reference Information Item

Im Abschnitt über das Character Information Item wurden bereits die Vordefinierten Textersetzungsmuster eingeführt, um die als Metasymbole dienenden Zeichen auch im Informationsbereich von XML-Dokumenten verwenden zu können.
Das für die fünf vordefinierten Symbole gewählte Verfahren steht auch dem Anwender zur Definition eigener Ersetzungsmuster offen. Die Definition kann ausschließlich in der Document Type Definition, oder dem DTD-Abschnitt eines Dokuments, erfolgen.
Diese Muster werden als Entitäten (engl. entities) bezeichnet.

Die Syntax ist wie folgt festgelegt (In XML-Spezifikation nachschlagen)

[71]GEDecl::='<!ENTITY' S  Name  S  EntityDef S? '>'
[4]NameChar::=Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
[73]EntityDef::=EntityValue | (ExternalID  NDataDecl?)
[9]EntityValue::='"' ([^%&"] | PEReference | Reference)* '"'
   | "'" ([^%&'] | PEReference | Reference)* "'"
[76]NDataDecl::=S  'NDATA' S  Name

Aus der Syntax ergeben sich zwei Klassen von Entitäten: Die durch eine URI und evtl. öffentlichen Namen identifizierten externen Entitäten, und die internen Entitäten, deren Inhaltsdefinition direkt rechts neben dem Schlüsselwort ENTITY gegen ist.
Die Verwendung von Entitäten kann an jeder Stelle des Informationsbereichs eines XML-Dokuments gestattet werden. Daher können Element- und Attributnamen keine Entitätsreferenzen enthalten.
Der Einsatz erfolgt, wie für die vordefinierten entities gezeigt, durch namentliche Referenzierung mit einem vorgestellten Kaufmanns-Und und einem abschließenden Semikolon.

Referenzierungssyntax: & entityName ;

Beispiel 7: Einige Entitätsdefinitionen
Beispiel 7: Einige Entitätsdefinitionen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<!DOCTYPE someContent [
(3)	<!ELEMENT someContent ANY>
(4)	<!ENTITY entA "xyz">
(5)	<!ENTITY entB SYSTEM "http://www.jeckle.de/vorlesung/xml/script.html">
(6)	<!ENTITY entC PUBLIC "-//FHA//Symbol//DE" "file://symbols">
(7)]>
(8)<someContent>
(9)&entA;
(10)&entB;
(11)&entC;
(12)</someContent>
Download des Beispiels


Das Beispiel zeigt die drei möglichen Ausprägungen der Entitätsdefinitionen. entA deklariert eine interne Entität, deren Auftreten durch die Zeichenfolge abc ersetzt wird.
Durch entB und entC werden externe Quellen angesprochen. Die verwendete Syntax ist dabei zu der bei NOTATIONs eingeführten identisch. Während entB ausschließlich eine lokal bekannte Referenz darstellt, bedient sich entC des PUBLIC-Identifiers um darüberhinaus auch eine öffentlich bekannte Quelle anzusprechen.
Im Dokument werden alle drei Entitäten über den selben Syntaxmechanismus eingebunden.

Innerhalb des Information Sets werden nicht-expandierte Entitäten durch das Element Unexpanded Entity Reference Information Item repräsentiert (für alle expandierten ist ihre Herkunft vollkommen transparent und für die Applikation nicht von Interesse).
Es definiert folgende Eigenschaften:

Unparsed Entity Information Item

Mit der XML-Syntaxproduktion 76 wird als zusätzlicher Entitätstyp die explizit nicht zu prüfende Entität (engl. unparsed entity) eingeführt. Sie kann beispielsweise dazu verwendet werden, um Binärdaten wie Bilder, Videos, o.ä. aus einem XML-Dokument zu referenzieren.

Beispiel 8: Eine ungeprüfte Entität
Beispiel 8: Eine ungeprüfte Entität
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<!DOCTYPE someContent [
(3)	<!ELEMENT someContent ANY>
(4)	<!NOTATION gif PUBLIC            
(5)    "-//Compuserve Information Services//NOTATION Graphics Interchange     
(6)        Format//EN">
(7)	<!ENTITY entA SYSTEM "xyz.gif" NDATA gif>
(8)]>
(9)<someContent>
(10)&entA;
(11)</someContent>
Download des Beispiels


Das Beispiel definiert zunächst die NOTATION für das Graphikformat GIF über dessen PUBLIC-Identifier. Diese wird innerhalb der Entität entA zur Definition der ungeprüften Inhaltsreferenz auf die Datei xyz.gif herangezogen.

Seitens des Information Sets stellt das Unparsed Entity Information Item eine Abwandlung der im vorhergehenden betrachteten Entitätsreferenz dar.
Im Einzelnen definiert der Information Set die Eigenschaften:

Die Darstellung der Abbildung 8 faßt die syntaktischen Elemente abgekürzt zusammen:

Kommentar- und PI-Struktur

Namespace Deklaration Information Item

Jedem im XML-Dokument definierten Namensraum ist ein Namespace Deklaration Information Item zugeordnet. Es enthält die notwendigen syntaktischen Details zur Identifikation des Namensraumes:

Beispiel 9: Beispiel eines Dokuments mit Namensräumen
Beispiel 9: Beispiel eines Dokuments mit Namensräumen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<root>
(3)	<elementA>...</elementA>
(4)	<elementB xmlns="http://www.fh-furtwangen.de">...</elementB>
(5)	<elementC xmlns:abc="http://www.xyz.com">
(6)		...
(7)		<abc:elementD/>
(8)	</elementC>
(9)</root>


Für das Beispiel lauten die Namensräume wie folgt:

Elementname
Namensraum
root
(Das Element befindet sich im leeren Namensraum)
elementA
(Das Element befindet sich im leeren Namensraum)
elementB
http://www.fh-furtwangen.de
elementC
(Das Element befindet sich im leeren Namensraum)
elementD
http://www.xyz.com

Eine ausführliche Betrachtung zur Verwendung von Namensräumen findet sich im entsprechenden Abschnitt.

Die Elemente des Information Set in der Zusammenstellung

Die Graphik der Abbildung 9 stellt alle diskutierten Elemente des Information Sets in der Übersicht mit ihren Beziehungen dar. Zur Veranschaulichung wurde eine einfache Graphenstruktur gewählt, die alle Informationseinheiten als Knoten (darstellt als Ellipsen) und alle zugelassenen Beziehungen als gerichtete Kanten zwischen diesen enthält. Zusätzlich ist an die Kanten die Art der Beziehung angetragen.
Den Ausgangspunkt der baumartigen Struktur eines XML-Dokuments bildet die im Zentrum abgebildete Primitive Document Information Item, die alle weiteren Inhalte eines Dokuments über die children-Kante als Kindknoten enthält. Ferner fällt in dieser Darstellung besonders auf, daß lediglich Element Information Items über weitere Kindknoten verfügen und so die charakteristische XML-Struktur herausbilden. Alle übrigen Primitive dienen überwiegend als Blattknoten des Baumes.

Beziehung zwischen XML-Syntax und Semantik

Die Graphik der Abbildung 10 setzt die durch den Infoset-Standard definierte Semantik und die darauf aufsetzenden Syntaxen in Beziehung. Der XML-Basisstandard definiert hierbei nur eine von mehreren möglichen Syntaxen zur Darstellung von Infoset-Ausprägungen. Ebenso denkbar wäre der Einsatz anderer Darstellungen gleicher Mächtigkeit wie beispielsweise der S-Expression aus LISP oder objektorientierte Umsetzungen.



Auf Basis der Definitionen des Information Sets läßt sich ein beliebiges XML-Dokument, welches den Strukturierungsprinzipien des Infosets folgt, als wohlgeformt (well-formed) charakterisieren.

Definition 5: Wohlgeformtes XML-Dokument
Definition 5: Wohlgeformtes XML-Dokument
Ein textartiges Objekt, dessen Inhalt folgenden Anforderungen genügt:
  • Das XML-Dokument nutzt eine DTD, oder enthält die Deklaration standalone="yes"
  • Zu jedem Start-Tag existiert genau ein Ende-Tag.
    Bei leeren Elementen können diese zu einem Tag zusammenfallen.
  • Korrekte Elementschachtelung, d.h. Elemente überlappen einander nicht.
  • Genau ein Wurzelelement.
  • Alle Attributwerte sind in einfachen oder doppelten Anführungszeichen.
  • Kein Start-Tag (oder Tag der ein leeres Element einleitet) enthält zwei oder mehr Attribute desselben Namens.
  • Keine Kommentare oder Processing Instructions innerhalb von Tags.
  • Kommentare beginnen und enden mit genau zwei Bindestrichen.
  • Die Sonderzeichen < und & treten nicht innerhalb von Elementinhalten oder Attributwerten auf.

siehe XML-Spezifikation


Der Textstrom des Beispiels 10 zeigt ein nicht-wohlgeformtes XML-Dokument, welches gegen eine Reihe der in Definition 5 verstößt:

Beispiel 10: Ein nicht wohl-geformtes XML-Dokument
Beispiel 10: Ein nicht wohl-geformtes XML-Dokument
(1)<?xml version="1.0"?>
(2)<root>
(3)	<elementA att=a oder b>
(4)		<elementB> iff a<b ==> ...
(5)	</elementA>
(6)	<elementC att1="42" att1="3.14">
(7)		<elementD <?do-something?> >
(8)	</elementC>
(9)		</elementD>
(10)	<!---- dies ist nicht erlaubt ---->
(11)</root>
Download des Beispiels


So findet sich in Zeile 3 ein nicht in die erforderlichen Anführungszeichen eingeschlossener Attributwert.
Der textuelle Elementinhalte des in Zeile 4 geöffneten Elements elementB enthält ein öffnendes Winkelklammersybol, welches um Fehler während des Einlesevorganges zu vermeiden durch die alternative Zeichensequenz &lt; hätte ersetzt werden müssen. Darüberhinaus fehlt das korrekte schließende Tag zum Öffnenden.
Innerhalb des Elements elementC der Zeile 6 wird zweifach ein identisch benanntes Attribut definiert.
Im öffnenden Tag des in Zeile 7 definierten Elements elementD findet sich eine -- dort nicht zugelassene -- Processing Instruction.
Überdies überlappen sich die Elementgrenzen der Elemente elementC und elementD und zusätzlich wird der in Zeile 10 plazierte Kommentar nicht durch die erforderlichen genau zwei Bindestriche eingegrenzt.

1.3   Namensräume

Die XML-Namensräume wurden schon verschiedentlich erwähnt. Sie bilden die wichtigste, und offensichtlichste Weiterentwicklung der XML-Urspezifikation seit ihrer Veröffentlichung.
Trotz ihrer engen Beziehung zum XML-Kernstandard bildet die Recommendation Namespaces in XML eine eigenständige Spezifikation. Aufgrund der engen syntaktischen Beziehung zum XML-Standard und der großen praktischen Bedeutung, sowie des Einflusses auf die weitere Entwicklung verschiedenster Sekundärstandards und XML-Sprachen, werden die Namensräume explizit in der Neuauflage des XML-Standards berücksichtigt. Einen Beleg hierfür bildet die Anmerkung zu Abschnitt 2.3 Common Syntactic Constructs. Dort wird von der -- laut Syntaxproduktion 5 erlaubten -- Verwendung des Doppelpunktes in Elementnamen abgeraten. Dies geschieht, um Mehrdeutigkeiten, oder schlichtweg der Verwirrung des Anwenders, vorzubeugen, da es sich beim Doppelpunkt um ein Symbol besonderer Bedeutung innerhalb der Namensraumdeklarationen handelt.

Warum Namensräume?
Die breite Entwicklung immer neuer XML-Sprachen führt zwangsläufig zu Mehrfachentwicklungen für ähnliche oder identische Problemstellungen. Technisch betrachtet äußerst sich dies -- bei natürlichsprachlicher Benennung der Elemente -- durch die Verwendung identischer Bezeichner in verschiedenen XML-Sprachen. Hierbei bilden die verschiedenen Sprachen Anwendungskontexte, innerhalb derer die Bezeichner, durch Einbezug der Anwendungssemantik, eindeutig sind; andernfalls kann unterstellt werden, daß bereits durch die Sprachentwicklung andere Benennungskonventionen gewählt worden wären.
In der Konsequenz der Verfügbarkeit verschiedenster XML-Sprachen für beliebige Anwendungsbereiche entsteht der (berechtigte) Wunsch existierende Sprachfragmente in eigene Sprachen zu integrieren, um so zeitraubenden und vielfach fehleranfälligen Mehrfachentwicklungen vorzubeugen. Jedoch tritt bei diesem Integrationsszenario die u. U. kontextabhängige Elementeindeutigkeit zu Tage.
Das Beispiel zeigt zwei Dokumente identischen Informationsumfanges, die lediglich strukturell differieren.

Beispiel 1: Ein Rechnungsdokument
Beispiel 11: Ein Rechnungsdokument
(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
(2)<Rechnung>
(3)   <Kunde>
(4)      <KundenNr>4711</KundenNr>
(5)      <Name>Max Mustermann</Name>
(6)      <Anschrift>
(7)         <Straße>Musterplatz 1</Straße>
(8)         <PLZ>12345</PLZ>
(9)         <Ort>Musterstadt</Ort>
(10)      </Anschrift>
(11)   </Kunde>
(12)   <Rechnungsposten>
(13)	...
(14)	</Rechnungsposten> 
(15)</Rechnung>


Beispiel 2: Eine alternative Rechnungsstruktur
Beispiel 12: Eine alternative Rechnungsstruktur
(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
(2)<Rechnung>
(3)	<Rechnungsanschrift>
(4)		<Kunde kundenNr="4711">
(5)			<Name>Max Mustermann</Name>
(6)			<Straße>Musterplatz 1</Straße>
(7)			<PLZ>12345</PLZ>
(8)			<Ort>Musterstadt</Ort>
(9)		</Kunde>
(10)	</Rechnungsanschrift>
(11)	<Lieferanschrift>
(12)   ...
(13)   </Lieferanschrift>
(14)	<Rechnungsposten>
(15)	...
(16)	</Rechnungsposten>
(17)</Rechnung>


Information Sets der beiden Beispieldokumente

Die beiden Bäume mit Information Set-Ausprägungen zeigen die Struktur der Beispieldokumente. Dabei sind Knoten die den selben Inhalt repräsentieren mit identischen Farben unterlegt, unabhängig davon um welchen Knotentyp es sich handelt. Die Character Information Item Knoten wurden aus Übersichtlichkeitsgründen weggelassen und durch Punkte angedeutet, sie sind jedoch für die vorliegende Betrachtung nicht von Interesse.

Einige der Elemente und Attribute werden in beiden Dokumenten mit gleichen Inhalten verwendet; z.B. Name, Ort oder PLZ. Dies äußert sich in identischen Teilbäumen unterhalb der Information Set-Knoten welche diese XML-Elemente repräsentieren. Hieraus läßt sich ableiten, daß die beiden vorgestellten Sprachen an den genannten Stellen keine strukturelle Differenz aufweisen.
Dagegen unterscheiden sich die Kindknoten der Elemente Rechnung und Kunde hinsichtlich ihrer Struktureigenschaften. So folgt im ersten Beispieldokument auf das Rechnung-Element direkt der Kunde, während im zweiten XML-Dokument zunächst ein Element mit dem Namen Rechnungsanschrift erwartet wird.
Dergleichen gilt für die Kindelemente des Kunden. Im zweiten Beispieldokument wird die diesem Element untergeordnete Kundennummer durch ein Attribut (kundenNr) dargestellt. Dagegen codiert das erste Beispiel diese Information direkt in den Elementinhalt.

Solange die beiden Dokumente in unterschiedlichen Anwendungswelten (Unternehmen o. ä.) verwendet werden, ist der gewählte Ansatz nicht problematisch. Bedenklich wird er jedoch in mindestens zweierlei Hinsicht:
Zunächst bei der „Mischung“ der beiden Dokumente. Dieser Wunsch tritt bei praktischen Problemstellungen häufig auf, wenn es um die Übernahme von XML-codierten Daten in ein anderes XML-Dokument geht. In der Konsequenz folgt das entstehende Zieldokument nicht mehr den Strukturierungsregeln eines der Ausgangsdokumente; mithin entsteht eine neue Dokumentstruktur, deren Regeln nicht explizit dokumentiert sind.
Eine weitaus größere Herausforderung stellt die Zusammenfassung und Veröffentlichung von XML-Strukturen in sog. Schemabibliotheken oder Datenbanken dar. Hier werden zwar die Dokumente nicht vereinigt, jedoch offenbart sich die gleiche Anwendungsdomäne (z.B. Rechnungsverwaltung, Stücklisten, Produktstrukturen) als problematisch, da sie die XML-Strukturen in direkte Konkurrenz treten läßt. In Zeiten immer stärker werdenden ökonomischen Flexibilisierungsdruckes erweist sich dies als äußerst kontraproduktiv, im Hinblick auf eine angestrebte Standardisierung. Die offene Konkurrenz verschiedener Dialekte innerhalb einer Domäne verzögert damit oft die Entscheidung zum Einsatz eines Sprachformates.

Einen anderen interessanten Anwendungsfall stellt der ausdrückliche Wunsch nach der Einbettung fremder Sprachelemente dar. Diese Form der Wiederverwendung knüpft an das durch öffentlich verfügbare XML-Formate eröffnete Anwendungsfeld an. Da nicht in jedem Fall ein alle Anforderungen erfüllendes existierendes XML-Format ermittelt werden kann, jedoch verschiedene vorhandene Formatteile des gewünschten Umfanges abdecken, entsteht der Wunsch nach einer selektiven Weiterverwendung. Ein bekanntes Beispiel bilden Freitexte in beliebigen XML-Sprachen, welche auf Teile des (X)HTML-Sprachumfanges zurückgreifen. Gleichzeitig ist damit die Semantik der Elemente durch den zugehörigen W3C-Standard festgelegt. XHTML selbst stellt ein interessantes Anwendungsbeispiel für die gemeinsame Verwendung verschiedener XML-Sprachen in einem Dokument dar. So können Web-Seiten neben den bekannten Textstrukturen (XHTML) auch mathematische Symbole und Formeln (in der XML-Sprache MathML) und Vektorgraphiken (in der XML-Sprache SVG) enthalten.
Als Nebeneffekt der Wiederverwendung existierender XML-Sprachen verringern sich mögliche Fehlerquellen, was in der Konsequenz zur Erhöhung der Qualität der entstehenden Sprachen führt.

Zusammenfassend lassen sich die (Hinter-)Gründe der Namensraumeinführung wie folgt darstellen:

Definition 6: Namensräume
Definition 6: Namensräume
XML-Namensräume stellen eine XML-basierte Syntax zur Verfügung um Element- und Attributnamen eines Vokabulars eindeutig zu identifizieren und so Bedeutungsüberschneidungen durch gleichbenannte Elemente- oder Attribute in zu unterscheidenden Vokabularen auszuschließen. XML-Namensräume bilden damit die notwendige Voraussetzung zur freien dezentralen Entwicklung eigener Vokabulare ohne die Möglichkeit einer späteren Syndikatisierung zu verlieren.


Konzept der Namensräume:
Die Recommendation Namespaces in XML definiert die Syntax und Semantik der Namensräume. Ihr Konzept wurde rund ein Jahr nach Verabschiedung der ersten XML-Version eingeführt. Daher wurde der Kompatibilität mit bereits existierenden XML-Dokumenten große Priorität eingeräumt.

Grundidee der Namensräume ist es, die Element- und Attributnamen dergestalt zu erweitern, daß (auch nach Vereinigung beliebiger Dokumente wieder) eineindeutige Bezeichner entstehen. Dies könnte durch anwenderdefinierte Erweiterungen geschehen, sie trügen jedoch wiederum die Gefahr in sich, daß sie unbeabsichtigt mehrfach benutzt würden.
Daher scheidet der unkoordinierte Einsatz solcher Namenserweiterungen aus. Jegliche Koordination bedingt jedoch inhärent eine zentrale Vergabestelle zur Registrierung der vergebenen Namen, die über die Eindeutigkeit wacht und Mehrfachnutzungen unterbindet.
Die Einführung einer solchen Stelle hätte jedoch einen unüberschaubaren Verwaltungsaufwand bedeutet, den das W3C nicht zu leisten im Stande wäre. Man nehme nur als Vergleich das Vergabeverfahren von Einträgen des Internet Domain Name Systems (DNS), welches bereits dezentral durch die einzelnen nationalen Domain-Registrars gehandhabt wird. Der dort anzutreffende Aufwand hätte sich für XML-Namensräume potenziert, legt man pro Domainadresse mehrere Namensräume zugrunde.

Ziel des W3C war es, durch die Namensräume einen gleichermaßen mächtigen als auch leicht zu handhabenden und zu administrierenden Identifikationsmechanismus zu etablieren. Offenkundig wird diesem Anspruch nur ein (überwiegend) dezentraler, aber dennoch die Eineindeutigkeit garantierender, Ansatz gerecht.
Diesen Anforderungen genügt das aus IETF RFC 2396 bekannte Namensschema der Uniform Resource Identification (URI) (später aktualisiert in IETF RFC 2732). Es kombiniert zentrale und dezentrale Elemente in der Handhabung, und ermöglicht so -- trotz Existenz und Pflege einer zentralen Registratur -- größtmögliche Flexibilität in der Anwendung. Der bekannteste Einsatz von URI-Namen ist der im World-Wide-Web allgegenwärtige Uniform Ressource Locator (URL) (IETF RFC 1738); einer Untermenge der URI.
Die zentrale Komponente findet sich im Domainnamen verwirklicht. Er ist entweder durch die IP-Adresse (konkret: IPv4-Adresse; im Falle des RFC 2732: der IPv6-Adresse) oder deren literaler Repräsentation gegeben. Unterhalb der Domainebene kann durch deren Verwalter eine beliebige Strukturierung vorgenommen werden. Die verschiedenen Ebenen werden dabei durch ISO-10646/ASCII #x2F „/“ voneinander abgetrennt.
Wie auch bereits bei URLs notwendig, ist das Schema (URI scheme) (z.B. http) zwingend mitanzugeben.

Trotz der Möglichkeit XML-Namensräume durch URLs zu identifizieren handelt es sich dabei nicht die Bezeichnung einer Internetquelle. Die verwendete Zeichenkette dient ausschließlich Benennung der im Namensraum versammelten XML Element Information Items und Attribute Information Items.
Die Auflösung des Namensraumbezeichners durch einen XML-Prozessor ist nicht vorgesehen.

Nachfolgend ist die in definierte Syntax einer URI wiedergegeben. Sie wurde behutsam an die in der XML-Spezifikation verwendete BNF-Notation (In XML-Spezifikation nachschlagen) angepaßt, ohne jedoch die Produktionen in ihrer Struktur zu verändern.

[URI1]URI-reference::=(absoluteURI | relativeURI)? ("#" fragment)?
[URI2]absoluteURI::=scheme ":" ( hier_part | opaque_part )
[URI3]relativeURI::=( net_path | abs_path | rel_path ) [ "?" query ]
[URI4]hier_part::= ( net_path | abs_path ) ("?" query)?
[URI5]opaque_part::=uric_no_slash uric?
[URI6]uric_no_slash::=unreserved | escaped | ";" | "?" | ":" | "@" |
   "&" | "=" | "+" | "$" | ","
[URI7]net_path::="//" authority abs_path?
[URI8]abs_path::="/" path_segments
[URI9]rel_path::=rel_segment abs_path?
[URI10]rel_segment::=(unreserved | escaped |
   ";" | "@" | "&" | "=" | "+" | "$" | "," )+
[URI11]scheme::=alpha (alpha | digit | "+" | "-" | "." )*
[URI12]authority::=server | reg_name
[URI13]reg_name::=( unreserved | escaped | "$" | "," |
   ";" | ":" | "@" | "&" | "=" | "+" )+
[URI14]server::=((userinfo "@")? hostport)?
[URI15]userinfo::=( unreserved | escaped |
   ";" | ":" | "&" | "=" | "+" | "$" | "," )*
[URI16]hostport::=host (":" port)?
[URI17]host::=hostname | IPv4address
[URI18]hostname::=( domainlabel "." )* toplabel (".")?
[URI19]domainlabel::=alphanum | alphanum *( alphanum | "-" ) alphanum
[URI20]toplabel::=alpha | alpha (alphanum | "-" )* alphanum
[URI21]IPv4address::=digit+ "." digit+ "." digit+ "." digit+
[URI22]port::=digit*
[URI23]path::=(abs_path | opaque_part)?
[URI24]path_segments::=segment ("/" segment)*
[URI25]segment::=pchar* (";" param)*
[URI26]param::=pchar*
[URI27]pchar::=unreserved | escaped |
   ":" | "@" | "&" | "=" | "+" | "$" | ","
[URI28]query::=uric*
[URI29]fragment::=uric*
[URI30]uric::=reserved | unreserved | escaped
[URI31]reserved::=";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
   "$" | ","
[URI32]unreserved::=alphanum | mark
[URI33]escaped::="%" hex hex
[URI34]hex::=digit | "A" | "B" | "C" | "D" | "E" | "F" |
   "a" | "b" | "c" | "d" | "e" | "f"
[URI35]digit::="0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
   "8" | "9"
[URI36]uric_no_slash::=unreserved | escaped | ";" | "?" | ":" | "@" |
   "&" | "=" | "+" | "$" | ","

Die Produktionen alphanum, lowalpha sowie upalpha zur Konstruktion der alphanumerischen Namen wurden aus Übersichtlichkeitsgründen weggelassen.

Neben einigen anderen gängigen URI-Varianten stellt das nachfolgende Beispiel einige der möglichen syntaktisch korrekten URIs zusammen, die für die späteren Betrachtungen von Interesse sind.

Beispiel 3: Gültige URIs
Beispiel 13: Gültige URIs
(1)http://www.wi.fh-furtwangen.de
(2)http://meinrechner.wi.fh-augsburg.de
(3)mailto:mario@jeckle.de
(4)ftp://ftp.shareware.com
(5)http://www.jeckle.de/xml/vorlesung/script.htm#Namespaces
(6)#EinfuehrungUndUeberblick
(7)urn:oasis:names:specification:docbook:dtd:xml:4.1.2
(8)urn:oid:1.3.6.1.2.1.27
(9)org.omg/standards/UML


Exkurs: URIs, URLs, URNs ...

Vielfach wird in der Praxis die Abgrenzung der im Internet gebräuchlichen Adressierungs- und Identifikationsmechanismen nicht trennscharf vollzogen.
Darüberhinaus trat im Laufe der Entwicklung eine merkliche Bedeutungsverschiebung insbesondere zwischen der Uniform Resource Identifikation und den als WWW-Adressen genutzten Uniform Resource Locators ein.

Gegenwärtig wird die Begriffsabgrenzung wie in Abbildung 12 schematisch dargestellt vollzogen:

Die Definitionen der verschiedenen URI-Typen im Zusammenhang
Web-Referenzen 1: Weiterführende Links
Web-Referenzen 6: Weiterführende Links




Verwendung von Namensräumen:
Am naheliegendsten wäre nach der Zielsetzung der Verwendung von URIs zur eindeutigen Benennung von XML-Element- und Attributnamen, die URI direkt vor dem XML-Bezeichner zu plazieren, evtl. separiert durch ein Trennsymbol wie den Doppelpunkt „:“.
Hieraus entstünden dann, auf jeden Fall eindeutige, Element- und Attributnamen wie beispielsweise für das erste Beispieldokument dieses Kapitels (die URI http://www.example.com/sales werde zur Identifizierung verwendet):

(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
(2)	<http://www.example.com/sales:Rechnung>    
(3)		<http://www.example.com/sales:Kunde>       
(4)			<http://www.example.com/sales:KundenNr>4711</http://www.example.com/sales:KundenNr>       
(5)			<http://www.example.com/sales:Name>Max Mustermann</http://www.example.com/sales:Name>       
(6)			<http://www.example.com/sales:Anschrift>          
(7)				<http://www.example.com/sales:Straße>Musterplatz 1</http://www.example.com/sales:Straße>          
(8)				<http://www.example.com/sales:PLZ>12345</http://www.example.com/sales:PLZ>          
(9)				<http://www.example.com/sales:Ort>Musterstadt</http://www.example.com/sales:Ort>       
(10)			</http://www.example.com/sales:Anschrift>    
(11)		</http://www.example.com/sales:Kunde>    
(12)	<http://www.example.com/sales:Rechnungsposten>
(13)		... 
(14)	</http://www.example.com/sales:Rechnungsposten>
(15)</http://www.example.com/sales:Rechnung>

Bei entsprechender Nachbearbeitung des zweiten Beispieldokumentes mit einem anderen URI-identifizierten Namensraum, entstehen eindeutige Element- und Attributnamen, die nicht mehr kollidieren.

Jedoch verstößt diese Lösung gegen die in Produktion 5 der XML-Spezifikation formulierte syntaktische Einschränkung. Sie erlaubt das in URIs elementare Pfadtrennersymbol („/“) (aus den URI-Produktionen 8, 24 und 31) nicht in XML-Namen (#x2F findet sich nicht in den in Produktion 85 aufgeführten Unicode-Blöcken).
Die Integration der Namensräume auf diesem Weg hätte daher eine Modifikation der XML-Spezifikation nach sich gezogen. Diese erweiternde Aufweichung der zugelassenen Namen für Elemente und Attribute hätte jedoch mit der Kompatibilität zu SGML gebrochen, und somit eine der Grundforderungen der XML-Entwicklung verletzt.
Darüberhinaus ist die Spezifikation vollständiger URIs für Menschen „unhandlich“ und reduziert die Lesbarkeit der entstehenden XML-Dokumente.

Als Ausweg und pragmatischer Kompromiß zwischen eineindeutigen Namenspräfixen und Lesbarkeit wurde daher ein zweistufiges Verfahren eingeführt. Es erlaubt die Zuordnung von URIs zu Präfixen. Dieser Vorgang wird als „Bindung“ bezeichnet.
Diese Präfixes können Attributen oder Elementen vorangestellt werden, um sie in bestimmte Namensräume zu übernehmen.
Für die Präfixe gelten dieselben Bildungsgesetze wie für die Element- und Attributnamen. Im Einzelnen legt die Namespace Recommendation fest: (im XML-Namespace-Dokument nachschlagen)

[NS7]Präfix::=NCName
[NS4]NCName::=(Letter | '_') (NCNameChar)*
[NS5]NCNameChar::=Letter | Digit | '.' | '-' | '_'
   | CombiningChar
   | Extender

Anmerkung: Die rechten Seiten der Produktionen beziehen sich entweder auf die dargestellten Definitionen des Namespace-Standards oder auf Syntaxregeln der XML-Recommendation.

Die Bindung einer URI an ein -- gemäß Produktion NS7 frei wählbares -- Präfix geschieht durch das reservierte Attribut xmlns.
Die Syntax hierfür wird mit

[NS2]PräfixedAttName::='xmlns:' NCName

angegeben.

Nach der Bindung der URI an das Präfix kann dieses jedem Element oder Attribut vorangestellt werden, um es in den Namensraum zu übernehmen.
Hierdurch verändert sich die Produktion Name aus der XML-Spezifikation zum qualifizierten Namen, der durch die Voranstellung des Präfixes entsteht. Der rechts vom trennenden Doppelpunkt folgende Elementname stellt den lokalen Namen (innerhalb des Namensraumes dar). Dieser lokale Name darf keinen Doppelpunkt mehr enthalten; insofern schränkt Produktion NS8 in Verbindung mit NS4 die Festlegung der Produktion 5 der XML-Spezifikation ein.

[NS6]QName::=(Präfix ':')? LocalPart
[NS8]LocalPart::=NCName

Während der Verarbeitung eines XML-Dokuments, das Namensräume nutzt, ersetzt ein XML-Prozessor jedes Auftreten eines deklarierten Präfixes transparent durch die gebundene URI.
Prozessoren, welche die Namensraum-Spezifikation unterstützen, werden als namespace aware bezeichnet. Alle anderen Prozessoren treffen die durch NS6 eingeführte Unterscheidung zwischen Präfix und LocalPart eines qualifizierten Namens nicht und betrachten die Kombination aus Präfix und Element- bzw. Attributnamen als Bezeichner. Die Präfix-URI-Bindung durch das xmlns:...-Attribut wird hierbei als gewöhnliches XML-Attribut betrachtet und führt daher zu keinen Validierungsfehlern. (Die Einschränkung der Produktion 5, ein Name dürfe nicht mit der Zeichenfolge (('X'|'x') ('M'|'m') ('L'|'l')) beginnen, stellt in der XML-Spezifikation lediglich einen Hinweis dar.)

Semantisch bildet die durch xmlns eingeleitete Deklaration ein Pseudoattribut, da es für die maschinelle Verarbeitung vorbehalten und mit festelegter Bedeutung ausgestattet ist, welche durch den XML-Dokumentautor nicht verändert werden kann.
Zusätzlich werden Namensraumdeklarationen durch Programmiersprachenschnittstellen nicht den gewöhnlichen Attributen gleichgestellt betrachtet, sondern nehmen, wie auch im Information Set, dort eine Sonderstellung ein.

Anmerkung: Auf Webseiten und in Mailinglisten finden sich manchmal Formulierungen der Struktur {namespaceName}elementName (z.B. {http://www.w3.org/2001/XMLSchema}element oder {http://www.w3.org/1999/XSL/Transform}template).
Hierbei handelt es sich um eine zwar geläufige, aber nicht spezifikationskonforme Schreibweise!
Sie dient lediglich dazu, das prinzipiell beliebig wählbare Präfix einzusparen und den gewählten Namensraum hervorzuheben.
Strukturen dieses Stils sind jedoch keine gültigen XML-Dokumente!

Angewendet auf das betrachtete Beispiel läßt sich die URI http://www.example.com/sales an das Präfix myNS1 binden. Diese Bindung steht im definierenden Element (local name: rechnung) und allen untergeordneten zur Verfügung.

Beispiel 4: Dokument mit W3C-konformen Namensräumen
Beispiel 14: Dokument mit W3C-konformen Namensräumen
(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
(2)<myNS1:Rechnung xmlns:myNS1="http://www.xyz.com/sales">
(3)   <myNS1:Kunde>
(4)      <myNS1:KundenNr>4711</myNS1:KundenNr>
(5)      <myNS1:Name>Max Mustermann</myNS1:Name>
(6)      <myNS1:Anschrift>
(7)         <myNS1:Straße>Musterplatz 1</myNS1:Straße>
(8)         <myNS1:PLZ>12345</myNS1:PLZ>
(9)         <myNS1:Ort>Musterstadt</myNS1:Ort>
(10)      </myNS1:Anschrift>
(11)   </myNS1:Kunde>
(12)   <myNS1:Rechnungsposten>
(13)	<!--...-->
(14)	</myNS1:Rechnungsposten>
(15)</myNS1:Rechnung>
Download des Beispiels


Hinweis: Für das Attribut xmlns kann keine Namensraumdeklaration angegeben werden; es ist spezifikationsgemäß an keinen Namensraum gebunden.

Die Deklaration des Namensraumes mit der Präfixbindung kann auf beliebige hierarchisch höhergeordnete Elemente ausgelagert werden. In der Praxis hat es sich aus Übersichtlichkeitsgründen durchgesetzt, alle in einem XML-Dokument benutzten Namensräume mit ihren Präfixen zu Beginn des Dokuments im Wurzelelement zu definieren.
Das nachfolgende Beispiel zeigt dies anhand eines XHTML-Dokuments, das neben Elementen der Hypertextsprache auch mathematische Formeln und Vektorgraphiken enthält.

Beispiel 5: Ein XHTML-Dokument mit MathML- und SVG-Inhalten
Beispiel 15: Ein XHTML-Dokument mit MathML- und SVG-Inhalten
(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
(2)<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
(3)            xmlns:mml="http://www.w3.org/TR/REC-MathML"
(4)            xmlns:svg="http://www.w3.org/2000/svg">
(5)	<xhtml:head>
(6)		<xhtml:title>XHTML Dokument, mit MathML- und SVG-Inhalten</xhtml:title>
(7)	</xhtml:head>
(8)	<xhtml:body>
(9)		<xhtml:h1>Eine Û¢erschrift</xhtml:h1>
(10)		<mml:math>
(11)		<mml:mrow>
(12)			<mml:mi>x</mml:mi>
(13)			<mml:mo>=</mml:mo>
(14)			<mml:mfrac>
(15)				<mml:mrow>
(16)					<mml:mrow>
(17)						<mml:mo>-</mml:mo>
(18)						<mml:mi>b</mml:mi>
(19)					</mml:mrow>
(20)					<mml:mo>&PlusMinus;</mml:mo>
(21)					<mml:msqrt>
(22)						<mml:mrow>
(23)							<mml:msup>
(24)								<mml:mi>b</mml:mi>
(25)								<mml:mn>2</mml:mn>
(26)							</mml:msup>
(27)							<mml:mo>-</mml:mo>
(28)							<mml:mrow>
(29)								<mml:mn>4</mml:mn>
(30)								<mml:mo>&InvisibleTimes;</mml:mo>
(31)								<mml:mi>a</mml:mi>
(32)								<mml:mo>&InvisibleTimes;</mml:mo>
(33)								<mml:mi>c</mml:mi>
(34)							</mml:mrow>
(35)						</mml:mrow>
(36)					</mml:msqrt>
(37)				</mml:mrow>
(38)				<mml:mrow>
(39)					<mml:mn>2</mml:mn>
(40)					<mml:mo>&InvisibleTimes;</mml:mo>
(41)					<mml:mi>a</mml:mi>
(42)				</mml:mrow>
(43)			</mml:mfrac>
(44)		</mml:mrow>
(45)		</mml:math>
(46)		<svg:svg width="4cm" height="8cm">
(47)			<svg:ellipse cx="2cm" cy="4cm" rx="2cm" ry="1cm"/>
(48)		</svg:svg>
(49)	</xhtml:body>
(50)</xhtml:html>
Download des Beispiels


Definition 7: Namensraumidentifikation
Definition 7: Namensraumidentifikation
Jeder XML-Namensraum wird durch eine gültige URI identifziert. Diese URI dient ausschließlich der Benennung, daher muß sie nicht auf eine gültige Ressource verweisen.


Überschreiben des Vorgabe-Namensraums:
Aus den Beispielen ist leicht ersichtlich, daß die explizite Angabe des definierten Präfixes für jedes Element eines Namensraumes platzraubend und für die Zuordnung aller Elemente eines Teilbaumes zum selben Namensraum redundant und -- wegen des zusätzlichen Spezifikationsaufwandes -- unpraktikabel ist. Die mehrmalige explizite redundante (identische) Angabe des identifizierenden Präfixes bildet zusätzlich noch eine potentielle Fehlerquelle hinsichtlich Übertragungsfehlern und reiner Tippfehler bei manuell erstellten XML-Dokumenten.

Eine einfache Kompaktifizierungsvariante greift auf die aus den Programmiersprachen geläufigen Regeln für Namensräume zurück. Dort beinhaltet ein explizit geöffneter Block alle enthaltenen Elemente bis zum Blockendesymbol und faßt sie so zu einem Gültigkeitsbereich zusammen.
Dieses Prinzip läßt sich leicht auch auf XML-Dokumente, die immer eine streng hierarchische Baumstruktur aufweisen, anwenden.

Hierzu wird das xmlns-Attribut leicht modifiziert eingesetzt. Wird es ohne nachfolgendes Präfix und unter Weglassung des separierenden Doppelpunktes verwendet, so definiert es einen Vorgabenamensraum (default namespace). Dieser umfaßt neben dem Element, welches das Attribut beinhaltet, auch alle Kindelemente. Eine Ausnahme hiervon bilden untergeordnete Elemente, die explizit durch Präfix oder Redefinition des Vorgabenamensraumes einem anderen Namespace zugeordnet werden.

Das nachfolgende Beispiel zeigt dies für das bereits mit Namenräumen versehene Rechnungsdokument

Die syntaktische Definitionsform der Namensraumüberschreibung als XML-(Pseudo-)Attribut stellt hierbei sicher, daß für ein Element keine mehrmalige Überschreibung des Vorgabenamensraumes vorgenommen werden kann, da in diesem Falle das Attribut xmlns mehrfach im selben Elementkontext auftreten müßte, was der XML-Basisspezifikation widerspräche.

Beispiel 6: Rechnungsdokument mit überschriebenem Vorgabenamensraum
Beispiel 16: Rechnungsdokument mit überschriebenem Vorgabenamensraum
(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
(2)<Rechnung xmlns="http://www.xyz.com/sales">
(3)   <Kunde>
(4)      <KundenNr>4711</KundenNr>
(5)      <name>Max Mustermann</Name>
(6)      <Anschrift>
(7)         <Straße>Musterplatz 1</Straße>
(8)         <PLZ>12345</PLZ>
(9)         <Ort>Musterstadt</Ort>
(10)      </Anschrift>
(11)   </Kunde>
(12)   <Rechnungsposten>
(13)		<!--...-->
(14)	</Rechnungsposten>
(15)</Rechnung>
Download des Beispiels


Durch die Definition des Vorgabenamensraumes für das Element rechnung und all dessen Kindelemente wird derselbe Effekt erreicht wie durch die Präfixangabe im vorangegangenen Beispiel.
Diese Schreibweise stellt lediglich eine Abkürzung der expliziten Qualifizierung jedes einzelnen XML-Namens dar. Insbesondere führt die mehrmalige Redefinition des Vorgabenamensraumes nicht zu kaskadierten Namensräumen. Jeder Namensraum ist von allen umgebenden unabhängig definiert.
So kann das Dokument des XHTML-Beispiels auch dahingehend verändert werden, daß die Namensräume erst an der Stelle im Dokument deklariert werden, an der sie auch benötigt werden.

Beispiel 7: Ein XHTML-Dokument mit MathML- und SVG-Inhalten, unter Verwendung überschriebener Vorgabenamensräume
Beispiel 17: Ein XHTML-Dokument mit MathML- und SVG-Inhalten, unter Verwendung überschriebener Vorgabenamensräume
(1)<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
(2)<html xmlns="http://www.w3.org/1999/xhtml">
(3)	<head>
(4)		<title>XHTML Dokument, mit MathML- und SVG-Inhalten</title>
(5)	</head>
(6)	<body>
(7)		<h1>Eine Überschrift</h1>
(8)		<math xmlns="http://www.w3.org/1998/Math/MathML">
(9)		<mrow>
(10)			<mi>x</mi>
(11)			<mo>=</mo>
(12)			<mfrac>
(13)				<mrow>
(14)					<mrow>
(15)						<mo>-</mo>
(16)						<mi>b</mi>
(17)					</mrow>
(18)					<mo>+-</mo>
(19)					<msqrt>
(20)						<mrow>
(21)							<msup>
(22)								<mi>b</mi>
(23)								<mn>2</mn>
(24)							</msup>
(25)							<mo>-</mo>
(26)							<mrow>
(27)								<mn>4</mn>
(28)								<mo>&#160;</mo>
(29)								<mi>a</mi>
(30)								<mo>&#160;</mo>
(31)								<mi>c</mi>
(32)							</mrow>
(33)						</mrow>
(34)					</msqrt>
(35)				</mrow>
(36)				<mrow>
(37)					<mn>2</mn>
(38)					<mo>&#160;</mo>
(39)					<mi>a</mi>
(40)				</mrow>
(41)			</mfrac>
(42)		</mrow>
(43)		</math>
(44)		<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" svg:width="4cm" svg:height="8cm">
(45)			<ellipse cx="2cm" cy="4cm" rx="2cm" ry="1cm"/>
(46)		</svg>
(47)	</body>
(48)</html>
Download des Beispiels


Die Namensraumpräfixe können durch den Anwender frei vergeben werden. Sie dienen lediglich der abkürzenden Schreibweise und sind für die Namensraumauflösung unerheblich.
Daher werden zwei Elemente oder Attribute als gleich betrachtet, wenn sie lexikalisch in Namen und Namensraumidentifier übereinstimmen. Hierbei ist es unerheblich, ob der Namensraum explizit durch Präfixangabe oder durch Überschreiben des Vorgabenamensraumes definiert wurde.
Die Elemente der XML-Dokumente aus den Beispielen 18 und 19 befinden sich alle ausnahmslos im Namensraum http://www.example.com.

Beispiel 8: Namensraumpräfixe 1
Beispiel 18: Namensraumpräfixe 1
(1)<abc:ElementA xmlns:abc="http://www.example.com"
(2)				  xmlns:xyz="http://www.example.com">
(3)	<ElementB xmlns="http://www.example.com">
(4)		<ElementC/>
(5)	</ElementB>
(6)	<xyz:ElementB>
(7)		<abc:ElementC/>
(8)	</xyz:ElementB>
(9)</abc:ElementA>
Download des Beispiels


Beispiel 9: Namensraumpräfixe 2
Beispiel 19: Namensraumpräfixe 2
(1)<ElementA xmlns="http://www.example.com"
(2)             xmlns:myNamespace="http://www.example.com">
(3)   <foo:ElementB xmlns:foo="http://www.example.com">
(4)      <myNamespace:ElementC/>
(5)   </foo:ElementB>
(6)   <ElementB xmlns="http://www.example.com">
(7)      <myNamespace:ElementC/>
(8)   </ElementB>
(9)</ElementA>
Download des Beispiels


Die Abbildung zeigt das Beispieldokument in der Darstellung des W3C-Browsers Amaya.

Screenshot im Browser

Im Beispieldokument wird der Vorgabenamensraum dreimal, entsprechend der verschiedenen verwendeten XML-Sprachen, neu gesetzt. So wird auf html und alle direkt untergeordneten Elemente der URI-identifizierte Namensraum http://www.w3.org/1999/xhtml angewendet. head, title und body sowie dessen Kindelemente finden sich demnach, da sie keinen eigenen Namensraum definieren, ebenfalls im so definierten Vorgabenamensraum.
mrow als hierarchisch tieferstehendes Element redefiniert den Namensraum zu http://www.w3.org/TR/REC-MathML. Daher werden das Element mrow sowie all dessen Kindelemente (im Beispiel: ellipse) auch diesem zugeordnet.
Die Attribute width, height, cx , ... verfügen über kein explizites Namensraumpräfix und sind daher dem leeren Namensraum zugeordnet.
Auf den MathML-Namensraum folgend wird der Vorgabenamensraum zu http://www.w3.org/2000/svg redefiniert. Auch hier gelten dieselben Regeln, d.h. der überschriebene Vorgabenamensraum erstreckt sich auf alle Kindelemente.
Mit dem schließenden Tag svg endet auch dessen Namensraum. Alle folgenden Elemente befinden sich wieder im umgebenden Namensraum, der zu Beginn des Dokuments mit http://www.w3.org/1999/xhtml festgelegt wurde.
Die nachfolgende Graphik stellt die Namensräume nochmals farblich hervorgehoben dar.
Ein weiteres Beispiel findet sich in der Namespace-Recommendation.

Graphische Darstellung der Namensräume

Der XML-Namensraumstandard des W3C sieht die beiden im Vorhergehenden diskutierten Varianten exklusiv zueinander vor. D.h. für ein Element, welchem bereits durch Präfixangabe eine Namensraumzuordnung gegeben wurde, kann nicht zusätzlich der Vorgabenamensraum überschrieben werden. Deklarationen der Form <xyz:abc xmlns="..." ...> sind widersprüchlich; und daher illegal. (in der XML-Namespace Recommendation nachschlagen)

Das abschließende Beispiel 20 zeigt die Verwendung zweier Vokabulare (SVG und MathML), die beide ein mit set benanntes Element definieren.
Durch die Deklaration der jeweiligen Namensräume unterscheiden sich die qualifizierten Namen, die dem (gleichnamigen) Elementnamen die Namensraum-URI voranstellen.

Beispiel 10: Namensräume im realen Einsatz
Beispiel 20: Namensräume im realen Einsatz
(1)<?xml version="1.0"?>
(2)<document>
(3)	<svg xmlns="http://www.w3.org/2000/svg">
(4)		<g transform="translate(100,100)">
(5)			<text id="TextElement" x="0" y="0" style="font-family:Verdana; font-size:35.27; visibility:hidden">
(6)			It's alive!
(7)				<set attributeName="visibility" attributeType="CSS" to="visible" begin="3s" dur="6s" fill="freeze"/>
(8)			</text>
(9)		</g>
(10)	</svg>
(11)	
(12)	<math xmlns="http://www.w3.org/1998/Math/MathML">
(13)		<set>
(14)	  		<ci> b </ci>
(15)	  		<ci> a </ci>
(16)	  		<ci> c </ci>
(17)		</set>
(18)	</math>
(19)</document>
Download des Beispiels


Präzedenz des explizit zugeordneten Namensraumes:
Eine explizit durch Präfixzuordnung vorgenommene Namensraumfestlegung besitzt Präzedenz gegenüber dem evtl. überschriebenen Vorgabenamensraum.
Findet daher für ein Element sowohl die Überschreibung des Vorgabenamensraumes, als auch gleichzeitig die Namensraumfestlegung durch explizite Präfixzuordnung statt, so wird das Element demjenigen Namensraum zugeordnet, der durch die URI identifiziert wird, an den das Präfix gebunden ist.
Dies gilt insbesondere auch dann, wenn ein und dasselbe Element sowohl über ein Präfix, als auch eine Überschreibung des Vorgabenamensraumes verfügen.
Das XML-Dokument aus 21 illustriert dies beispielhaft. So wird ElementA -- durch Überschreibung des Vorgabenamensraumes -- dem Namensraum urn:namspaces:Namespace1 zugeordnet und diese Festlegung auch an das Kindelement ElementB weitergegeben.
Das Kindelement ElementC hingegen überschreibt die Vorgabe des Elternelements durch explizite Präfixangabe und ist daher dem durch urn:namespace:Namespace2 identifizierten Namensraum zugeordnet.
Für ElementD findet sich sowohl eine Namensraumdefinition, welche durch Überschreiben des Vorgabenamensraumes zu urn:namespace:Namespace3 stattfindet, als auch eine Präfix-gebundene Definition an den Namensraum urn:namespace:Namespace2. Gemäß der Präzedenz der expliziten Festlegung durch Präfix wird ElementD jedoch ausschließlich dem Namensraum zugeordnet, an den das angegebene Präfix ns1 gebunden ist. Im Beispiel ist dies die URI urn:namespace:Namespace2.

Beispiel 11: Präzedenzregel
Beispiel 21: Präzedenzregel
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<ElementA xmlns="urn:namspaces:Namespace1"
(3)			     xmlns:ns1="urn:namespace:Namespace2"
(4)			     xmlns:ns2="urn:namespace:Namespace3">
(5)	<ElementB/>
(6)	<ns1:ElementC/>
(7)	<ns1:ElementD xmlns="urn:namespace:Namespace3"/>
(8)</ElementA>
Download des Beispiels


Aufheben der Namensraumzuweisung:
Durch Überschreibung des Vorgabenamensraumes mit der Zeichenkette leeren Inhalts -- formal der Zuweisung der leeren URI als Namensraumidentifikator -- kann eine bestehende Namensraumdefinition aufgehoben werden. Als Resultat entsteht eine Situation identisch zu einem Dokument ohne festgelegte Namensräume, d.h. die Elemente finden sich im leeren Namensraum.

Beispiel 12: Aufheben von Namensraumdeklarationen
Beispiel 22: Aufheben von Namensraumdeklarationen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<Adressen>
(3)	<table xmlns="http://www.w3.org/TR/REC-html40">
(4)		<tr>
(5)			<td>Name</td>
(6)			<td>Adresse</td>
(7)		</tr>
(8)		<tr>
(9)			<td>
(10)				<Vorname xmlns="">Max</Vorname>
(11)			   <Nachname xmlns="">Mustermann</Vorname>
(12)			</td>
(13)			<td>
(14)				<Straße xmlns="">Musterstr. 1</Straße>
(15)				<PLZ xmlns="">12345</PLZ>
(16)				<Ort xmlns="">Musterstadt</Ort>
(17)			</td>
(18)		</tr>
(19)	</table>
(20)</Adressen>


Das Beispiel 22 zeigt die notwendigen Deklarationen zur Aufhebung der Vorgabenamensraumdefinition.
So wird zwar für das Element table und alle seine Kindelemente der Vorgabenamensraum auf http://www.w3.org/TR/REC-html40 gesetzt, dies jedoch für die Kindelemente Vorname, Nachname, Straße, PLZ und Ort durch die Festlegung xmlns="" explizit für das jeweilige Element aufgehoben.

Die Aufhebung von definierten Namensräumen kann ausschließlich durch die Überschreibung des Vorgabenamensraum erfolgen. Eine Bindung der leeren URI an ein Präfix zur späteren Verwendung ist nicht zugelassen.

Namensräume für Attribute:
Abweichend von der Mimik für Elemente, dort wirkt sich ein überschriebener Vorgabenamensraum auch immer auf die Kindelemente aus, wird eine Namensraumdeklaration auf Elementebene nicht auf Attribute propagiert.
Diese Festlegung der Spezifikation mag insbesondere unter Kenntnis der Baumstruktur der Infosets, welche Attribute und Elemente gleichermaßen als Kindknoten der beherbergenden Elementinformationseinheit darstellt, verwundern. Eine mögliche Begründung dieser Asymmetrie mag in der besonderen Rolle der Attribute zur Informationsdarstellung liegen. So wird teilweise damit argumentiert, daß Attribute üblicherweise unabhängig vom aktuell umgebenden Element sein sollten und daher nur zur Darstellung von Daten herangezogen werden sollten, die nicht über einen direkten Bezug zum sie umgebenden Element verfügen.
In der Konsequenz müssen Attribute immer explizit mit einem Namensraumpräfix versehen werden, um sie einem Namensraum zuzuordnen.
Beispiel 23 zeigt die Anwendung der Namensräume auf Attribute. So befinden sich weder das Attribute att1 des Elements ElementB, noch dasjenige von ElementD in einem Namensraum. Das mit dem Wert XYZ versehene Attribut att2 des Elements ElementC wird hingegen -- aufgrund des explizit angegebenen Präfixes -- dem Namensraum http://www.example.com/NS2 zugeordnet.
Ferner illustriert ElementC die Rolle der Namensräume als Bestandteil des identifzierenden Namens von Elementen und Attributen. Aufgrund der Interpretation des Namensraumes als Benennungsbestandteil darf das att2 benannte Attribut mehrfach auftreten, da die Zuhilfenahme des Namensraumes die eindeutige Identifikation gestattet.

Beispiel 13: Namensräume für Attribute
Beispiel 23: Namensräume für Attribute
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<Wurzelelement>
(3)	<ElementA xmlns:NS1="http://www.example.com/NS1" xmlns:NS2="http://www.example.com/NS2">
(4)		<ns2:ElementB att1="...">
(5)			<ElementD att1="..." xmlns="http://www.example.com/NS3">
(6)				<ElementC att2="ABC" NS2:att2="XYZ"/>
(7)			</ElementD>
(8)		</ns2:ElementB>
(9)	</ElementA>
(10)</Wurzelelement>


Definition 8: Namensraumvererbung
Definition 8: Namensraumvererbung
Namensräume, die durch Überschreiben des Vorgabenamensraumes zugewiesen werden wirken sich ausschließlich auf Elemente und deren direkte oder transitive Kindelemente aus, sofern diese den Namensraum nicht wieder verändern.
Namensräume, die durch explizite Präfixangabe zugewiesen werden, wirken sich ausschließlich auf dasjenige Element aus vor dessen Name das Präfix plaziert ist.
Namensräume für Attribute werden ausnahmslos durch explizite Präfixangabe festgelegt und gelten ausschließlich für das Attribut selbst.


Ausgehend von der Vererbungsregel für Namensräume, sowie der Präzedenz expliziter Präfixangaben lassen sich daher folgende Auswertungsregeln definieren:

Ein Element befindet sich in demjenigem Namensraum ...

  1. ... an den das vorangestellte Präfix gebunden ist.
    Verfügt das Element über kein Namensraumpräfix, so befindet es sich in demjenigen Namensraum ...
  2. ... der auf diesem Element durch Überschreibung des Vorgabenamensraumes definiert wurde.
    Findet für dieses Element keine Überschreibung des Vorgabenamensraumes statt, so befindet es sich in demjenigen Namensraum ...
  3. ... der für das Elternelement gilt, sofern er dort Vorgabenamensraum ist.
    Man beachte: Das gilt im vorangehenden Satz umschließt sich nicht nur die Überschreibung des Vorgabenamensraumes im direkten Elternelement, sondern auch eine dort geltende Namensraumüberschreibung die in dessen Elternelement oder dessen Elternelement ... stattfand.
    Findet in keinem der Elternelemente eine Überschreibung des Vorgabenamensraumes statt, so befindet sich das Element in demjenigen Namensraum ...
  4. ... der leer ist (d.h. im leeren Namensraum).

Ein Attribut befindet sich in demjenigem Namensraum, der durch explizite Präfixangabe festelegt wurde.

Internationale URIs und Namensraumidentifikatoren:
Die Berücksichtigung von Zeichen, die in XML v1.1 zugelassenen, deren Nutzung in den klassischen URIs nach RFC 2396 bzw. RFC 2732 jedoch untersagt ist, führt zur Einführung des neuen Begriffes des Internationalized Resource Identifiers (IRI). Diese Neuschöpfung stellt im Kern eine URI-Fassung dar innerhalb der Leerzeichen sowie diverse Sonderzeichen zulassen sind. Diese internationalisierten Identifikatoren werden durch einen im Spezifikationsentwurf festgelegten Algorithmus in syntaktisch korrekte URIs umgewandelt.
Beispiel 24 zeigt gültige IRIs und jeweils dahinter in Klammern angegeben die daraus resultierende URI-Darstellung.

Beispiel 14:
Beispiel 24:
(1)http://www.{iri-}example.com (http://www.%7Biri-%7Dexample.com)
(2)mailto:marc léon@example.org (mailto:marc%20l%E9on@example.org)


Kompatibilität zu älteren Dokumenten:
Elemente, für die weder ein expliziter Namensraum durch Präfix definiert ist, noch ein Namensraum von einem Elternelement übernommen werden kann, sind einem leeren Namensraum zugeordnet; konzeptionell entspricht dies einem NULL-Präfix.
Somit befinden sich alle Elemente, die keinem Namensraum angehören, automatisch in einem gemeinsamen Namensraum, der an keine URI gebunden ist.

Zusammenfassend gelten somit folgende Prinzipien:

Web-Referenzen 2: Weiterführende Links
Web-Referenzen 7: Weiterführende Links


1.4   Dokument-Typ-Definitionen

Die Dokument-Typ-Definition (DTD) stellt eine an die EBNF angelehnte reguläre Sprache zur Formulierung von XML-Grammatiken zur Verfügung.
Ursprünglich wurde diese textuelle Notation zur Spezifikation von XML-Strukturen mit SGML eingeführt. Zur Verwendung in XML wurde der Sprachumfang lediglich reduziert, und um einige -- im neuen Anwendungskontext nicht benötigte -- Konstrukte bereinigt.
Inzwischen haben die sehr stark Dokumenten-orientierten DTDs gegenüber den XML-Schemasprachen an Bedeutung verloren. Mittelfristig ist, wegen der deutlich gesteigerten Ausdrucksmächtigkeit, mit dem vollständigen Übergang zu Schemasprachen zu rechnen.
Nachfolgend sollen jedoch die Grundzüge des DTD-Mechanismus vorgestellt werden, um seiner historischen Bedeutung gerecht zu werden. Ebenso soll hierdurch ein Grundverständnis für die existierenden Sprachdefinitionen geweckt werden.

Dokumenttypdeklaration:
Prinzipiell stellt die DTD eine eigenständige, vom XML-Dokument losgelöste, Informationseinheit dar. Ihre Rolle entspricht der der Klasse in der objektorientierten Programmierung, welche schablonenartig die Struktur und die inhaltlichen Charakteristika beliebig vieler konkreter Ausprägungen festlegt. In dieser Analogie agiert das XML-Dokument wie ein Objekt einer spezifischen Klasse.
Daher ergibt sie die folgende Definition als Erweiterung der Wohlgeformtheit fast intuitiv:

Definition 9: Gültiges XML-Dokument
Definition 9: Gültiges XML-Dokument
Ein XML-Dokument heißt gültig (valid), wenn es über eine Dokument-Typ-Definition verfügt, und konform zu dieser aufgebaut ist.
(In XML-Spezifikation nachschlagen)


Implizit folgt hieraus, daß die Wohlgeformtheit eine schwächere Stufe der Gültigkeit, und damit Voraussetzung hierfür, darstellt.
Entsprechend der Unterscheidung in well-formed und valid ergeben sich zwei Klassen von XML-Prozessoren: nicht-validierende und validierende. Beide Typen prüfen die Wohlgeformtheit des eingehenden Textstromes. Zusätzlich testet ein validierender Prozessor die Konformität des XML-Dokuments zu seiner DTD.
(In XML-Spezifikation nachschlagen)

Die am Markt verfügbaren XML-Editierwerkzeuge beinhalten zumeist einen validierenden Parser, der die Konformitätsprüfung zu einer gegebenen DTD erlaubt. Ferner bieten viele Hersteller, oder Open-Source-Initiativen, eigenständige Parser-Module zur Validierung von XML-Dokumenten an.

Üblicherweise liegt die DTD in Form einer separaten (Text-)Datei vor, welche durch das XML-Dokument referenziert wird. Zu diesem Zwecke kann im Prolog des XML-Dokuments durch das Schlüsselwort DOCTYPE die physische Lokation der DTD angegeben werden.
(In XML-Spezifikation nachschlagen)

Die Syntax einer DOCTYPE-Deklaration lautet (In XML-Spezifikation nachschlagen) :

[28]doctypedecl::='<!DOCTYPE' S Name (SExternalID)?
   S? ('[' (markupdecl | DeclSep)* ']' S?)? '>'
[28a]DeclSep::=PEReference | S
[29]markupdecl::=elementdecl | AttlistDecl | EntityDecl | NotationDecl
   | PI | Comment

Die von SGML übernommene Syntax erinnert äußerlich leicht an die im XML-Dokument verwendete, weist jedoch mehr Ähnlichkeit zum Aussehen der Kommentare in XML auf.
So wird auch die DOCTYPE-Deklaration durch eine öffnende Winkelklammer und ein Ausrufezeichen eingeleitet. Daran schließt sich -- im Falle einer externen DTD -- die SYSTEM- oder PUBLIC-Deklaration an. XML-Dokument-interne Grammatikdefinitionen werden in eckigen Klammern innerhalb der DOCTYPE-Deklaration eingefügt.

Anwendungsbeispiele finden sich im Abschnitt zum Document Type Definition Information Item des Information Sets.

Alternativ zur externen Ablage der DTD kann diese auch ganz oder teilweise in das XML-Dokument eingebettet werden. Dieser Anteil der DTD innerhalb des XML-Dokuments wird als internal subset bezeichnet. Konsequenterweise wird der extern des Dokuments abgelegte DTD-Anteil daher mit dem Begriff external subset belegt.
Beispiele zur Definition interner Subsets finden sich in den Betrachtungen der XML-Information Set Items zu Notationen und Entitäten.
Anmerkung: Existieren in einem internen und externen Subset Festlegungen zum selben (identisch benannten) Informationselement, so überschreibt die des internal Subsets die extern getroffenen Definitionen.

Wie Produktion 29 bereits andeutet, erlaubt der DTD-Mechanismus die Strukturdefinition verschiedener Elemente aus dem XML-Information Set. Die wesentlichen hierbei sind: Elemente und Attribute. Ferner können durch die DTD Entitäten, Notation und Processing Instructions definiert werden.

Web-Referenzen 2: Weiterführende Links
Web-Referenzen 8: Weiterführende Links
JAXP: SUNs Standard-Parsing-API für Java
XML Instance -- Ein validierender Dokumenteditor
XML Authority -- Ein DTD-Editor
XML Spy -- Dokument- und DTD-Editor


Definition von Elementen:
Der offensichtlichste Anteil der Struktur eines XML-Dokuments wird durch seine Elemente gebildet. Ein einzelnes Element stellt auch (siehe Definition im Information Set) den minimalsten Umfang eines gültigen XML-Dokuments dar.
(In XML-Spezifikation nachschlagen)

Die Syntax zur Definition eines Elements lautet (In XML-Spezifikation nachschlagen) :

[45]elementdecl::='<!ELEMENT' S Name S contentspec S? '>'
[46]contentspec::='EMPTY' | 'ANY' | Mixed | children
[51]Mixed::='(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
   | '(' S? '#PCDATA' S? ')'

Jedes Element wird durch die SGML-Syntax der öffnenden Winkelklammer, gefolgt von einem Ausrufezeichen, eingeleitet. Daran schließt sich der Elementname an.
In runden Klammern wird dann das Inhaltsmodell, d.h. die erlaubten Kindelemente, spezifiziert. Sind keine Kindelemente erlaubt, d.h. es handelt sich um ein leeres Element, so ist stattdessen das Schlüsselwort EMPTY anzugeben.
Eine Besonderheit bildet das durch ANY ausgedrückte Inhaltsmodell. Es erlaubt das beliebige Auftreten von Elementen aus der DTD. Ebenso ist textueller Inhalt (#PCDATA) zugelassen.

Zulässige Kindelemente sind neben allen namentlich definierten Elementen der DTD auch Freitexte (#PCDATA für parsed character data, die keine Auszeichnungssymbole enthalten dürfen). Sollen im Elementinhalt Zeichen verwendet werden, die auch als Metasprachensymbole dienen -- wie < oder & --, so müssen diese durch die vordefinierten Textersetzungsmuster ausgedrückt werden.
Über freie Texte und explizite Kindelemente hinaus bietet der DTD-Mechanismus keinerlei Unterstützung zur näheren Definition der Inhalte eines Elements an. Diese, gerade bei Daten-orientierten XML-Dokumenten schmerzhafte, Einschränkung hat mit zur Definition der XML-Schemasprachen geführt, die sich u.a. die Überwindung dieser Einschränkung zum Ziel setzen.
Die Kindelemente werden durch namentliche Aufzählung in der Reihenfolge ihres im Dokument erwarteten Auftretens benannt. Zur Gruppierung können Elemente durch Klammerung zusammengefaßt werden.
Zur Steuerung der Auftrittshäufigkeit von Elementen und Elementgruppen existieren drei Operatoren.

Als Kombination aus explizit benannten Elementen und beliebigen Markup-freien Texten ergibt sich das gemischte Inhaltsmodell.
Aus historischen Gründen folgt dieses Inhaltsmodell immer derselben Struktur (siehe Produktion 51): Auf das Schlüsselwort #PCDATA folgen die zugelassenen Elemente in exklusiver ODER-Beziehung.
Hinter der zunächst etwas kryptisch anmutenden Formulierung verbirgt sich ein kleiner Kunstgriff, um diese zunächst widersprüchlich anmutende Dualität zwischen markupfreiem (#PCDATA) und explizit ausgezeichnetem Inhalt aufzuheben. Das für diesen Anwendungsfall in der XML-Spezifikation vorgegebene mixed content Model erlaubt eine Mischung aus frei formulierter Information und Markupinhalten. Hierzu werden #PCDATA und das gewünschte Element zunächst exklusiv zueinander deklariert (symbolisiert durch den trennenden senkrechten Strich |); im Anschluß wird - durch den Stern -- die beliebig häufig hintereinandergereihte Wiederholung dieser Auswahlentscheidung vereinbart.
(In XML-Spezifikation nachschlagen)

Definition 10: Gemischtes Inhaltsmodell
Definition 10: Gemischtes Inhaltsmodell
Kann ein Element sowohl über Zeichenketten-artigen als auch Element-wertigen Inhalt verfügen, so wird sein Inhaltsmodell als gemisches Inhaltsmodell (mixed content model) bezeichnet.
Innerhalb eines solchen Elements dürfen Unicodezeichen und die zugelassenen Elemente in wahlfreier Kombination auftreten.


Nachfolgend wird eine einfache Projektverwaltung, zur Organisation von Mitarbeitern und ihrer Zuordnung zu Projekten, als durchgängiges Beispiel verwendet.

Beispiel 1: Einige Elementdefinitionen
Beispiel 25: Einige Elementdefinitionen
(1)<!ELEMENT ProjektVerwaltung (Person+, Projekt+)>
(2)<!ELEMENT Person (Vorname+, Nachname, Qualifikationsprofil?)>
(3)<!ELEMENT Qualifikationsprofil (#PCDATA | Qualifikation | Leistungsstufe)*>
(4)<!ELEMENT Qualifikation (#PCDATA)>
(5)<!ELEMENT Leistungsstufe (#PCDATA)>
(6)<!ELEMENT Vorname (#PCDATA)>
(7)<!ELEMENT Nachname (#PCDATA)>
(8)<!ELEMENT Projekt EMPTY>
Download des Beispiels


Das Beispiel zeigt einige verschiedene Elementdefinitionen.
So kann ein Element des Typs ProjektVerwaltung mehrere, jedoch mindestens ein Personen-Element sowie auch mehrere Projekt-Elemente enthalten.
Innerhalb von Personen-Elementen können mehrere, wiederum jedoch mindestens ein Vornamen und genau ein Nachname auftreten. Das Auftreten des mit Qualifikationsprofil benannten Kindelements ist optional.
Über ein leeres Inhaltsmodell (Schlüsselwort EMPTY) verfügt das Element Projekt. Ihm dürfen keine Kindelemente im XML-Dokument folgen.
Die drei Elemente Ueberschrift, Vorname und Nachname erlauben jeweils das Auftreten markupfreien Textes in ihrem Elementinhalt.
Für Qualifikationsprofil ist das mixed content model verwirklicht. Es erlaubt in XML-Dokument das Auftreten des Elements Qualifikation oder Leistungsstufe an jeder beliebigen Stelle innerhalb eines (markupfreien) Freitextes.

Beispiel 2: Beispieldokument zur gegebenen DTD
Beispiel 26: Beispieldokument zur gegebenen DTD
(1)<?xml version="1.0" encoding="ISO-8859-1"?>
(2)<!DOCTYPE ProjektVerwaltung SYSTEM "http://www.jeckle.de/vorlesung/xml/examples/projektverwaltung1.dtd">
(3)<ProjektVerwaltung>
(4)   <Person>
(5)   <Vorname>Hans</Vorname>
(6)   <Nachname>Hinterhuber</Nachname>
(7)   </Person>
(8)   <Person>
(9)     <Vorname>Franz</Vorname>
(10)     <Vorname>Xaver</Vorname>
(11)     <Nachname>Obermüller</Nachname>
(12)     <Qualifikationsprofil>
(13)     IT-Kompetenz verschiedene Betriebssysteme und <Leistungsstufe>professionelle</Leistungsstufe> <Qualifikation>Programmierung</Qualifikation> verschiedener Programmiersprachen
(14)     <Qualifikation>Entwickler</Qualifikation> von 1988-1990
(15)     <Qualifikation>Projektleiterfunktion</Qualifikation> von 1990-93 im X42-Projekt in Abteilung AB&amp;C
(16)   </Qualifikationsprofil>
(17)   </Person>
(18)   <Projekt/>
(19)</ProjektVerwaltung>
Download des Beispiels


Das Beispiel zeigt ein gültiges XML-Dokument zu den bisherigen Elementdefinitionen.
Es zeigt die Nutzung des mehrfachen Auftretens des Elements Vorname innerhalb der Person, sowie die Anwendung des mixed content models -- einschließlich Einsatz des Textersetzungsmusters des Und-Symbols -- für das Qualifikationsprofil.

Definition von Attributen:
Die Syntax der Attributdefinition ist wie folgt festgelegt:

[52]AttlistDecl::='<!ATTLIST' S Name AttDef* S? '>'
[53]AttDef::=S Name S AttType S DefaultDecl
[54]AttType::=StringType | TokenizedType | EnumeratedType
[55]StringType::='CDATA'
[56]TokenizedType::='ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' |
   'NMTOKEN' | 'NMTOKENS'
[57]EnumeratedType::=NotationType | Enumeration
[59]Enumeration::='(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
[60]DefaultDecl::='#REQUIRED' | '#IMPLIED'
   | (('#FIXED' S)? AttValue)

Auch die Syntax der Attributdefinition in der DTD ist SGML entlehnt; daher auch hier die öffnende Winkelklammer und das Ausrufezeichen als einleitendes Symbol. Darauf folgt der Name des Elements, an die die Attributliste gebunden wird. Leicht wird ersichtlich, daß Attribute nicht wie Elemente vollkommen frei definiert werden können, sondern immer im Kontext des nutzenden Elements stehen. In der Folge ist es daher unmöglich, dieselbe Attributdefinition mehreren Elementen zuzuordnen.
An den Namen des Attribut-beinhaltenden Elements schließen sich die eigentlichen Deklarationen an. Im einfachsten Fall bestehen sie lediglich aus dem eindeutigen Attributnamen, einem Datentyp (gemäß der Produktionen 55 und 56) sowie der Angabe, ob es sich um ein optionales (#IMPLIED) oder zwingend anzugebendes (#REQUIRED) Attribut handelt.
Das Angebot der zur Verfügung stehenden Datentypen spiegelt die präsentationsorientierte Vergangenheit der Vorgängersprache SGML wieder. So fehlen Programmiersprachen-orientierte Primitivtypen vollständig. Das mit CDATA -- für character data -- benannte Äquivalent zum Elementinhaltstyp #PCDATA erlaubt lediglich die Beschränkung der Attributwerte auf Zeichenketten-artige Inhalte.
In Erweiterung der IMPLIED-Angabe können Attribute als mit Vorgabewerten belegt und zusätzlich als konstant (#FIXED) deklariert werden. Ihre vorgegebenen Werte werden, auch bei fehlender Angabe im XML-Dokument, durch einen validierenden XML-Parser an die verarbeitende Applikation weitergegeben. Darüberhinaus prüft der Parser für Konstanten, ob der angegebene Attributwert mit der Vorgabe übereinstimmt.
Eine besondere Bedeutung kommt den Typen ID, IDREF und IDREFS zu. Durch sie ist ein rudimentärer Refenzierungsmechanismus, für den die Gültigkeit der Referenzen durch einen validierenden XML-Prozessor geprüft werden kann, verwirklicht. Alle Attributwerte des Typs ID bilden einen Dokument-weiten Namensraum (der jedoch außer Verwendung desselben Begriffs nicht mit den XML-Namespaces in Verbindung steht!). Auf diese Schlüssel kann durch Attribute des Typs IDREF und IDREFS verwiesen werden. IDREF realisiert hierbei eindeutige Verweise, während IDREFS die Angabe einer Liste von Verweiszielen erlaubt. Im einheitlichen Namensraum aller definierten ID-Attribute liegt eine der Hauptschwächen des angebotenen Referenzierungsmechanismus. So ist eine typisierende Einschränkung der erlaubten Referenzziele nicht vorgesehen. Da IDREF(S)-Attribute alle Werte annehmen können, die dokumentweit in ID-Attributen auftreten, kann potentiell auf jede definierte ID verwiesen werden, unabhängig davon ob dieser Verweis semantisch sinnvoll ist. Darüberhinaus können -- insbesondere in großen Dokumenten -- durch die fehlende Partitionierung des ID-Namensraumes Konflikte (und damit invalide Dokumente) durch mehrfachauftretende IDs auftreten. Auch die Teilung von Dokumenten in ID-konfliktfreie Einheiten stellt hierbei keine Lösung dar, da der Referenzierungsmechanismus nicht dokumentübergreifend angelegt ist und daher nicht auf Elemente anderer XML-Quellen zugreifen kann.
Als Lösung dieser angerissenen Problemstellungen bieten sich neben den (deutlich mächtigeren) Referenzierungsmechanismen der XML-Schemasprachen auch dokumentübergreifende Verweise -- wie u.a. in der im Kapitel 2.1 diskutierten W3C-Sprache XLink verwirklicht -- an.
Eine einfache Variante anwenderdefinierter Datentypen werden durch Aufzählungstypen angeboten. Sie werden durch Benennung der Alternativen gebildet. Syntaktisch werden diese, durch Oder-Verknüpfungen voneinander abgetrennt, in runden Klammern dem Attributnamen nachgestellt.

Das nachfolgende DTD-Beispiel erweitert die betrachteten Elementdeklarationen um Attributdefinitionen.

Beispiel 3: Vollständige Beispiel-DTD
Beispiel 27: Vollständige Beispiel-DTD
(1)<!ELEMENT ProjektVerwaltung (Person+, Projekt+)>
(2)<!ATTLIST ProjektVerwaltung
(3)	version CDATA #FIXED "1.0">
(4)
(5)<!ELEMENT Person (Vorname+, Nachname, Qualifikationsprofil?)>
(6)<!ATTLIST Person
(7)	PersID ID #REQUIRED
(8)	Gehaltsgruppe (1 | 1a | 2) "1a"
(9)	mitarbeitInProjekt IDREFS #REQUIRED>
(10)
(11)<!ELEMENT Qualifikationsprofil (#PCDATA | Qualifikation | Leistungsstufe)*>
(12)<!ELEMENT Qualifikation (#PCDATA)>
(13)<!ELEMENT Leistungsstufe (#PCDATA)>
(14)<!ELEMENT Vorname (#PCDATA)>
(15)<!ELEMENT Nachname (#PCDATA)>
(16)<!ELEMENT Projekt EMPTY>
(17)<!ATTLIST Projekt
(18)	ID ID #REQUIRED
(19)	date CDATA #IMPLIED
(20)	budget CDATA "10000"
(21)	Projektleiter IDREF #REQUIRED
(22)	Mitarbeiter IDREFS #REQUIRED>
Download des Beispiels


Das Beispiel zeigt verschiedene Attributdeklarationen. Zunächst date als ein simples optionales Zeichenkettenattribut vom Typ CDATA.
budget und version stellen die beiden möglichen Erweiterungen, einerseits durch Angabe eines Vorgabewertes (in Anführungszeichen dem Datentyp nachgestellt), andererseits durch zusätzliche Erklärung des Vorgabewertes als konstant (#FIXED-Angabe), dar.
Die Möglichkeit eines anwenderdefinierten Aufzählungstyps ist in Gehaltsgruppe genutzt. Die Alternative 1a ist darüberhinaus als Vorgabewert definiert.
Zwischen den einzelnen Projekten und verwalteten Personen können über die Attribute PersID bzw. ID und mitarbeitInProjekt bzw. Projektleiter und Mitarbeiter Referenzierungsbeziehungen aufgebaut werden. Auch hier zeigen sich zwei Einschränkungen der ID/IDREF-Semantik deutlich: So können für Personen und Projekte nicht Identifikationsschlüssel aus demselben Namensraum vergeben werden, da diese bei Doppelbelegung kollidieren. Bei automatisch generierten Attributwerten ist daher applikationsseitig sicherzustellen, daß jeder Wert nur höchstens einmal im Dokument auftritt. Da eine spätere Vereinigung von Dokumenten nicht auszuschließen ist, verschärft sich diese Forderung zu über Zeit und Raum eindeutigen Attributbelegungen.
Zusätzlich wird deutlich, daß innerhalb des Projekt-Elements nicht sicherzustellen ist, daß die Attribute Projektleiter und Mitarbeiter ausschließlich auf Attribute innerhalb des Personen-Elements verweisen. So wäre die Zuordnung einer innerhalb von Projekt vergebenen ID zum Attribut Projektleiter desselben Elements korrekt und würde durch einen validierenden Parser akzeptiert.

Definition von Entitäten und Notationen:
Die Document-Type-Definition bietet die Möglichkeit, eigene Textersetzungsmuster (sog. Entitäten) durch den Anwender zu definieren. Dieses Sprachmerkmal hat jedoch -- wegen verschiedenster Probleme -- keinen Eingang in den XML-Schemamechanismus gefunden. Daher sei es hier nur der Vollständigkeit halber einführend erwähnt.
Hinzuweisen ist jedoch bereits jetzt auf die daher abzusehende Problematik beim Übergang von existierenden DTDs zu gleichmächtigen Schemadefinitionen, da ein äquivalentes Sprachmittel dort nicht mehr zur Verfügung stehen wird. Daher sollte bei neu zu erstellenden XML-Grammatiken ganz auf die Definition eigener Entitäten verzichtet werden.

Die XML-Spezifikation definiert selbst fünf Entitäten: die bekannten Textersetzungsmuster der Metasprachensymbole. Daher ist die Referenzierungssyntax (einleitendes &-Symbol gefolgt vom Namen der Entität und abschließendem Semikolon) bereits geläufig.
Zur Definition einer Entität stehen die im Abschnitt Unexpanded Entity Reference Information Item vorgestellten Strukturen zur Verfügung.
Dort finden sich auch Beispiele eigener Definitionen.

Die in enger Verbindung mit den Entitäten stehenden Notationen zur Realisierung von Ersetzungsmustern, die keine XML-codierten Inhalte (z.B. Binärdaten) beinhalten, sind beispielhaft sowie in Syntax und Semantik im Abschnitt unparsed Entities vorgestellt.

1.5   XML Schemasprachen

Neben den Document Type Definitions ist in jüngerer Zeit ein alternativer Ansatz in den Blickpunkt des Interesses gerückt: die XML-Schemasprachen.
Sie setzen die Emanzipation der Metasprache XML von ihrer Vorgängersprache SGML fort. Bereits in engem zeitlichem Bezug zur Veröffentlichung der XML-Recommendation wurde mit XML Data ein erster Ansatz vorgestellt. In der Zwischenzeit fanden verschiedene konkurrierende Vorschläge ein breites Interesse. Übereinstimmende Zielsetzung aller verschiedenen vorgeschlagenen Schemasprachen ist die Schaffung eines Sprachdefinitionsmechanismus, der die Dokumenten-orientierten Strukturen und Inhaltsmodelle der DTD überwindet.
An die Spitze der Bemühungen setzte sich eine Arbeitsgruppe des W3C zur Definition einer XML-Schemasprache, unter Berücksichtigung der bekanntesten und verbreitetsten Vorschläge. Durch sie wurde im Mai 2001 der XML Schema-Standard des W3C veröffentlicht.

Der Begriff Schema ist der im Datenbankumfeld gebräuchlichen Terminologie entlehnt. Dort bezeichnet er Informations- oder Datenmodelle als Konstruktionsvorlage oder Dokumentation eines Datenbankdesigns. Hierzu muß ein Schema nicht unbedingt in einer graphischen Datenmodellierungssprache vorliegen, sondern kann beispielsweise auch die Tabellenstruktur einer relationalen Datenbank bezeichnen.

Zur Notwendigkeit einer Schemasprache:
Zum Zeitpunkt der Konzeption der Metasprache SGML war das Anwendungsfeld klar umrissen und im wesentlichen auf die Digitalisierung vormals papiergestützter Dokumentation festgelegt. Daraus erklärt sich auch die Mächtigkeit der Document Type Definition, der angebotenen Grammatiksprache zur Darstellung der Dokumentstrukturen.
Insbesondere war weder die Daten-orientierte Verwendung von SGML, noch die rund 30 Jahre später einsetzende Weiterentwicklung (eigentlich: Reduktion) zur eXtensible Markup Language abzusehen.
Die inzwischen eingesetzte breite Anwendung von XML-Sprachen zur Darstellung beliebiger Inhalte läßt jedoch die Beschränkungen und Unzulänglichkeiten des DTD-Mechanismus für diesen Anwendungen offenkundig werden.

Nachfolgend sind einige der durch Nutzung des DTD-Mechanismus zur Beschreibung Daten-intensiver Strukturen induzierten Einschränkungen zusammengestellt:

Technische Ansätze:
Prinzipiell lassen sich die in der Vergangenheit vorgeschlagenen Ansätze zur Definition einer Schemasprache in vier Kategorien unterscheiden:

  1. Orientierung am bestehenden DTD-Mechanismus.
    Erweiterungen des bestehenden Mechanismus um zusätzliche Sprachelemente.
  2. Orientierung an der programmiersprachlichen Interpretation.
    Versuch XML und ein Ausführungsmodell möglichst eng zu koppeln.
  3. Orientierung an Wissensdarstellungen
    Interpretation des Schemas einer XML-Sprache als Wissen über die Sprache.
  4. XML-Sprachen zur Inhaltsbeschreibung.
    Da XML i.A. zur Beschreibung beliebigster Informationen herangezogen werden kann, ist die Verwendung auch für die Beschreibung von XML-Strukturen denkbar.

Die naheliegendste Option dürfte die Erweiterung des bestehenden DTD-Sprachumfanges bilden. Durch geeignete Modifikationen und Ergänzungen ließen sich alle, mit Ausnahme der letzten, identifizierten Unzulänglichkeiten beheben.
Konzeptionell lassen sich zwei Erweiterungsvarianten aufzeigen. Zunächst die Möglichkeit, die XML-DTDs um Elemente der ursprünglichen SGML-DTD zu erweitern. In der Konsequenz nähert sich XML, positiv formuliert, wieder der Ausdrucksmächtigkeit der Ursprache SGML an. Negativ formuliert, kann jedoch XML auf diesem Wege niemals Inhaltsstrukturen ausdrücken, die nicht durch SGML ausdrückbar sind, da die Mächtigkeit des SGML-DTD-Mechanismus eine natürliche Obergrenze der Erweiterbarkeit darstellt. Zusätzlich ist anzumerken, daß ein solcher Ansatz der ursprünglichen Intention der XML-Entwicklung -- ein leichter einsetzbares SGML zu schaffen -- entgegenläuft.
Eine der bekannten Ideen zur Erweiterung des DTD-Mechanismus stellt Datatypes for DTDs (DT4DTD) dar.
Alternativ zur Erweiterung hin zur SGML-Mächtigkeit ließe sich der bestehende XML-DTD-Mechanismus um neue zusätzliche Konstrukte anreichern, die nicht Bestandteil der SGML-DTD-Syntax sind. Dieser Ansatz böte den Vorteil, den Vorgängerstandard nicht berücksichtigen zu müssen und beliebige Erweiterungen in Syntax und Semantik einbringen zu können. Allerdings würde damit eine zentrale Forderung der XML-Entwicklung, die sich bereits im Abstract der XML-Recommendation findet, nicht berücksichtigt: die Untermengenbeziehung zu SGML. Durch eine Erweiterung, welche über die SGML-Mächtigkeit hinausreicht, würden legale (well formed und sogar valid) XML-Dokumente entstehen, die keine gültigen SGML-Dokumentinstanzen wären.

Die nachfolgende Graphik veranschaulicht die beiden Erweiterungsoptionen und die Argumente der geführten Diskussion.

Optionen zur Erweiterung des bestehenden DTD-Mechanismus

Die im zweiten Punkt angedeutete Umsetzung ist durch eine programmiersprachliche Verarbeitung der XML-Dokumente motiviert. Aus Sicht dieser Anwendungsfacette ist ein Schemamechanismus idealerweise so ausgelegt, daß er die transparente Umsetzung in Applikationsdatenstrukturen ermöglicht. Dahinter steht der Wunsch, den impedance mismatch, mithin den zu leistenden Abbildungsaufwand zwischen XML-Konstrukten und Datenstrukturen, möglichst gering zu halten.
Beispielsweise greift der -- durch den Einsatz im e-Commerce-System der Firma CommerceOne bekannt gewordene -- Vorschlag Schema for Object-Oriented XML (SOX) zur Definition der notwendigen Semantik der angebotenen Schemaprimitiven auf die bekannte plattformunabhängige Programmiersprache Java zurück.
Die aktuelle Version der Schemasprache SOX, die zur Definition der XML-Sprache xCBL eingesetzt wird, findet sich unter xCBL.org.

Der dritte technische Ansatz weist auf eine alternative Interpretation der XML-Grammatikstruktur hin. So spiegelt ein Schema auch immer Wissen über Struktur und Inhalt eines betrachteten Problembereichs wieder.
Der bekannteste Vorschlag -- die Document Content Description (DCD) -- nutzt zur Definition der Wissensstrukturen eines XML-Dokuments das Resource Description Framework (RDF) des World Wide Web Consortiums.
Der Ansatz hat sich durch Referenzimplementierungen durchaus als tragfähig und, wegen der RDF-basiertheit, als allgemein verwendbar erwiesen. Jedoch liegt hierin auch die offensichtlichste Limitierung. RDF als Metasprache der Schemasprache legt bereits eine gewisse Strukturierung aller Schemata zugrunde, da jedes gültige DCD-Schema definitionsgemäß ein RDF-Dokument darstellt. Ebenso ist die Semantik der eingesetzten RDF-Elemente bereits durch diese Spezifikation vorgegeben. Beide Punkte zusammengenommen offenbaren eine ausgeprägte Abhängigkeit von den weiteren RDF-Aktivitäten des World Wide Web Consortiums, die bisher nicht auf die Interdependenz von Schemasprache und Wissensbeschreibungsformat ausgerichtet ist.
Positiv fällt an DCD die Verwendung von XML zur Beschreibung von XML-Sprachen auf, womit auch die letzte der erhobenen Anforderungen zu erfüllen wäre.
Die Verknüpfung von RDF mit DCD als Schemasprache birgt allerdings ein potentielles Problem hinsichtlich der Validierbarkeit der entstehenden Strukturen. Durch den Rückgriff von DCD auf RDF entsteht bei der Angabe eines Schemas für RDF ein transitiver Zirkelschluß. In der Konsequenz wird zur Validierung eines XML-Dokuments, welches einer mittels DCD-formulierten Grammatik folgt, neben dem eigentlichen DCD-Schema des Dokuments auch das DCD-Metaschema und dessen Semantik-liefernde RDF-Beschreibung benötigt.

Diese Beschränkung mildert die vierte Familie von XML-Schemasprachen ab. Sie umfaßt die meisten Vorschläge, die alle als eigenständige XML-Sprachen ausgelegt sind; daher definieren sie ein eigenständiges XML-Vokabular zur Darstellung der benötigten XML-Strukturen, sowie die zugehörige Semantik.
In der Folge sind sie für die Meta-Schemaebene selbstbeschreibend. Das bedeutet das Schema eines Schemas kann durch sich selbst validiert werden. Da dieser Validierungsschritt statisch nur einmal erfolgen muß, kann er durch Schemawerkzeuge vorweggenommen werden.
In dieser Kategorie sind die meisten der bisher vorgeschlagenen Schemadialekte einzuordnen.

Die größte Bedeutung haben kontextfreie reguläre Sprachen zur Spezifikation von XML-Sprachstrukturen erlangt.
Eine Sprache dieses Typs entwickelt auch die W3C-Arbeitsgruppe zur Definition eines XML-Schemasprachstandards. Insbesondere berücksichtigt diese Aktivität explizit die Vorgängersprachen XML Data, DCD, SOX sowie Document Definition Markup Language. Die erwähnten konkurrierenden Vorschläge unterscheiden sich semantisch lediglich in Nuancen, bieten dem Anwender jedoch teilweise (optisch) stark unterschiedliche Konstrukte zur Syntaxspezifikation an.

Einen strukturell unterschiedlichen Ansatz verfolgt die durch Rick Jelliffe vorgeschlagene Sprache Schematron. Sie interpretiert ein Schema als Sammlung von Regeln, denen ein gegebenes Dokument genügen muß, um als gültig akzeptiert zu werden. Dies erlaubt die Formulierung mächtiger konktextsensitiver Einschränkungen, die während des Validierungsvorganges geprüft werden.
Die Umsetzung dieser Schemasprache setzt auf den XML-Standards XPath und XSLT auf.

W3Cs XML-Schema:
Jenseits aller existierenden verschiedenen Sprachvorschläge kommt dem W3C-Standard der XML Schema Description Language (XSD) die größte praktische Bedeutung zu.
Tim Berners-Lee verkündete in der Eröffnungsrede der WWW-Konferenz in Hong Kong am 2. Mai 2001 die Verabschiedung als Recommendation. Gleichzeitig deutete er bereits weitere Schema-Aktivitäten des World Wide Web Consortiums an.
XML-Schema bildet zusammen mit XML v1.0 2nd edition und den Namensräumen die Basis aller weiteren W3C-XML-Sprachstandards.

Aus formalen Gründen ist nicht mit dem Ersatz der DTD durch Schema zu rechnen. Jedoch werden mittelfristig neu entwickelte XML-Sprachen keine Grammatiken mehr in der Syntax der DTD entwickeln, sondern direkt Schemata definieren.

XSD bildet eine vollständig in XML-Syntax formulierte kontextfreie reguläre Grammatik zur Formulierung beliebiger XML-Strukturen ab. Hierbei handelt es sich um die bekannten Grundprimitive Element und Attribut, andere -- wie Entitäten oder Notationen -- können hingegen nicht durch Schemata ausgedrückt werden. Somit erfolgt durch XSD implizit eine Weiterentwicklung von XML, dahingehend, daß ursprünglich von SGML übernommene -- jedoch inzwischen als unpraktikabel oder potentiell fehlerträchtig angesehene -- Sprachbestandteile nicht mehr durch den Grammatikmechanismus unterstützt werden.
Gleichzeitig wurde, neben zahlreichen anderen Neuerungen, die Kommentarsyntax für Schemata neu definiert.

Inhaltlich gliedert sich der XSD-Sprachvorschlag in zwei große Teilbereiche: Part 1: Structures zur Definition von Inhaltsmodellen für Elemente, Attributstrukturen und wiederverwendbaren Strukturen und Part 2: Datatypes zur Festlegung diverser inhaltlicher Charakteristika wie Datentypen und konsistenzgarantierende Einschränkungen.
In beiden Teilen werden XML-Namensräume explizit berücksichtigt. Konzeptionell rekonstruiert XSD-Part1 zunächst die bekannte Mächtigkeit der DTD um so die evolutionäre Weiterentwicklung bestehender XML-Sprachen zu ermöglichen.
Der zweite Teil der XSD-Spezifikation definiert ein eigenständiges Typsystem, das neben der naheliegenden Verwendung im ersten Teil der Schemasprache XSD auch in anderen W3C-Arbeitsgruppen Verwendung findet. Inhaltlich baut auch Part2 auf den in der DTD definierten Typen auf und erlaubt zunächst direkt ihre Angabe in Schemata. Darauf aufbauend wird eine Fülle verschiedenster Typen angeboten, die an die verschiedenen verfügbaren Typsysteme aus den Programmiersprachen, Datenbanken und internationalen Standards angelehnt sind.
Alle durch XSD definierten Elemente, d.h. alle Primitive zur Definition eines eigenen Schemas, befinden sich im Namensraum http://www.w3.org/2001/XMLSchema, der üblicherweise an das Präfix xsd gebunden wird. Elemente und Attribute aus XML-Schema, die in Instanzdokumenten verwendet werden könne sind im Namensraum http://www.w3.org/2001/XMLSchema-instance (übliches Präfix xsi) organisiert.
Wegen des Umfanges der offiziellen Schemadokumente wird zusätzlich durch das W3C ein Part 0: Primer herausgegeben. Er stellt die beiden XSD-Teile in der Zusammenschau an Beispielen dar.

Nachfolgend werden die Bestandteile der Schemasprache XSD an einigen Beispielen eingeführt, die Struktur der Darstellung orientiert sich dabei an der bereits für die Vorstellung der DTD genutzten Gliederung. Im Verlauf wird das dort verwendete Beispiel zu einem XSD-konformen Schema weiterentwickelt.

Schemareferenz:
Jedes XML-Schema bildet als XML-Dokument eine eigenständige Speichereinheit, üblicherweise eine Datei. Mithin ist die Einbettung in das Instanzdokument, also die Bildung eines internal subset, nicht möglich.
Die Verbindung zwischen Schema und beschriebenem Dokument wird durch das in der XSD-Spezifikation vordefinierte Attribut schemaLocation bzw. noNamespaceSchemaLocation definiert. Eines dieser Attribute muß zwingend im Wurzelelement des XML-Dokuments angegeben werden.
Legt das Schema keinen Namensraum für die enthaltenen Deklarationen fest, d.h. alle darin deklarierten Elemente befinden sich im Vorgabenamensraum, so findet sich die Schemareferenz in noNamespaceSchemaLocation; andernfalls in schemaLocation.
Das nachfolgende Beispiel zeigt die Deklaration:

Beispiel 1: Definition einer Schemareferenz
Beispiel 28: Definition einer Schemareferenz
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<ProjektVerwaltung 
(3)	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
(4)	xsi:schemaLocation="http://www.jeckle.de/vorlesung/xml/examples/projektverwaltung.xsd">
(5)	... 


Im Beispiel wird zunächst der XML-Schema-Instanzen-Namensraum an das Präfix xsi gebunden. Dies ermöglicht die Einbindung von Elementen und Attributen aus der Schemaspezifikation in das eigene Dokument.
Als erste Nutzung eines solchen Elements aus XSD wird das Attribut schemaLocation im Wurzelelement mit der URI des Schemas als Wert belegt. Die Deklaration des XSI-Namensraumes ist daher zwingend. Die angegebene URI kann zur Ermittlung des Schemas für Validierungszwecke durch einen XML-Prozessor genutzt werden.

Durch die Einführung von XSD als weiterer Grammatiksprache verliert der Begriff der Gültigkeit an Qualität. So sind Dokumente denkbar, die zwar hinsichtlich einer gegebenen DTD als valid eingestuft werden, jedoch ein zugehöriges Schema verletzen.
Daher findet sich in der XSD-Spezifikation der Begriff der schema validness in Erweiterung der bisherigen (DTD-bezogenen) validness.

Definition 11: Gültigkeit hinsichtlich eines Schemas
Definition 11: Gültigkeit hinsichtlich eines Schemas
Ein XML-Dokument heißt gültig hinsichtlich eines Schemas (schema valid), wenn es über ein Schema verfügt, und konform zu diesem aufgebaut ist.


Der hier gegebene Gültigkeitsbegriff stützt sich explizit nicht auf der bisherigen validness ab, da er die Konformität hinsichtlich einer eventuell existierenden DTD außer Acht läßt.

So etabliert XML-Schema einen vom DTD-gebundenen Gültigkeitsbegriff losgelösten Validierungsmechanismus.
Aufgrund der Realisierung der Schemasprache als XML-Sprache ist jedes Schema auch ein XML-Dokument. Daher eröffnet sich die Möglichkeit, das Schema selbst durch ein Schema zu beschreiben. Dieses Schema für Schema -- auch Metaschema genannte -- XML-Dokument erlaubt die Validierung (im Sinne der schema validness) jedes Schemas. Damit erfüllt sich eine der Anforderungen an den Schemamechanismus: die Validierbarkeit der erstellten Schemata selbst, was für DTDs nicht gegeben war. In der praktischen Anwendung zeigt sich dies in der Möglichkeit, erstellte Schemata mit denselben Werkzeugen zu analysieren, verarbeiten und zu prüfen, die auch für Instanzdokumente verwendet werden.
Da das Metaschema selbst wiederum ein XML-Dokument ist, folgt, daß hierfür auch ein Schema angegeben werden kann. Die XML-Standardisierung hat hier -- nicht zuletzt um eine unendliche Reihung zur Validierung notwendiger Schemata zu vermeiden -- den Ansatz gewählt, das Schema für Schema durch sich selbst zu beschreiben.
Um den schrittweisen Übergang zu XSD zu befördern, hat die XSD-Arbeitsgruppe eine DTD für XSD herausgegeben. Mittels dieser können neu erstellte Schemata auch mit „klassischen“ Werkzeugen auf (DTD-)Gültigkeitkeit geprüft werden.
Die Abbildung stellt die getroffenen Aussagen und Validierungsbeziehungen nochmals graphisch zusammen.

Die Gültigkeitsbegriffe im Kontext

Die Schema-Definition:
Wuzelknoten jedes XSD-Dokuments ist das Element Information Item schema. Alle Definitionen eines Schemas sind direkte Kindknoten dieses Elements oder dessen Kindknoten.
Durch die Attribute des schema-Elements werden verschiedene Eigenschaften festgelegt, die für alle im Schema definierten Elemente und Attribute gelten.

Zunächst wird durch eine Reihe von Attributen das Verhalten des Schemas in Bezug auf Namensräume festgelegt. Als Besonderheit eines XML-Schemas fällt hier die ständige Berücksichtung von mindestens zwei Namensräumen ins Auge. Während ein Schema mit Elementen des Schemanamensraumes aufgebaut wird, trifft es zeitgleich Aussagen über einen zweiten Namensraum -- den Namensraum des Vokabulars für das das Schema erstellt wird. Dieser Namensraum wird Zielnamensraum (target namespace) genannt.
Daher findet sich im Attribut targetNamespace die URI des Zielnamensraumes. In diesen Namensraum werden automatisch alle durch das Schema deklarierten Elemente und Attribute übernommen. Als Konsequenz müssen diese in jedem Schema-gültigen XML-Dokument im entsprechenden Namensraum auftreten. Hierbei wird nicht zwischen expliziter Namensraumdeklaration durch ein gebundenes Präfix und impliziter Deklaration durch Überschreiben des Vorgabenamensraumes unterschieden.
Durch Angabe der Attribute elementFormDefault und attributeFormDefault kann der durch targetNamespace implizierte Namensraumzwang für das XML-Instanzdokument gelockert werden. Wird der Wert der beiden Attribute auf unqualified gesetzt, so können die Attribute auch außerhalb des Zielnamensraumes auftreten. Dies entspricht auch dem Vorgabeverhalten.

Definition von Elementen:
Als Obermenge der Ausdrucksmächtigkeit der DTD unterstützt auch XSD die Inhaltsmodelle

Generell wird jedes Element durch das XSD-Element element ausgedrückt.

Für unstrukturierten Inhalt bot die DTD lediglich Zeichenketten-artige Inhalte des Typs #PCDATA .
XML-Schema Part 2 definiert insgesamt 44 Primitivtypen. Darunter finden sich die aus der DTD bekannten Element- und Attributtypen, sowie eine Fülle Neuer.

Im Kern zerfallen die XSD-Typen in drei Typklassen:

Durch Erweiterungs- und Aggregationsmechanismen ergibt sich das in der nachfolgenden Abbildung dargestellte Typsystem.

Das XSD-Typsystem

Die Tabelle stellt die angebotenen Typen mit einigen Beispielen dar:

Tabelle  5: Typen in XSD-Schema Part 2
Tabelle 5: Typen in XSD-Schema Part 2
Typname
Beispiel
Bemerkung
   Hello &#xD;&#xA; World  
Jedes beliebige Unicode Symbol gemäß XML-Syntaxproduktion 2
&#20Hello&#20;World
Jedes beliebige Unicode Symbol außer Zeilenvorschub, Wagenrücklauf und Tabulatoren
normalizedString ist eine einschränkende Spezialisierung des Typs string
Hello World
Jeder normalizedString, unter Weglassung führender, abschließender und mehrfacher Leerzeichen (#x20), sowie Zeilenvorschüben (#xA) und Tabulatoren (#x9).
token ist eine einschränkende Spezialisierung des Type normalizedString
aName, _helloWorld, :notAGoodIdea
XML Name gemäß Syntaxproduktion 5.
Name ist eine einschränkende Spezialisierung des Typs token
xsd:element, element
Durch Namensraumpräfix qualifizierter Name gemäß Produktion 6 der XML Namespace Recommendation
aName, _anotherName, X
Name, der keinen Doppelpunkt enthält (non colonized name), gemäß Produktion 4 der XML Namespace Recommendation
-1.23, 12678967.543233, +100000.00, 210
Wertebereich: i*10-n, mit i, n aus integer, n>=0
Ein Prozessor muß mindestens 18 Dezimalstellen unterstützen
-9223372036854775808, ... -1, 0, 1, ... 9223372036854775807
Wertebereich: 263 <= long <= 263-1
long ist eine einschränkende Spezialisierung des Typs integer
-2147483648, ... -1, 0, 1, ... 2147483647
Wertebereich: -231 <= int <= 231-1
int ist eine einschränkende Spezialisierung des Typs long
-32768, ... -1, 0, 1, ... 32767
Wertebereich: -215 <= short <= 215-1
short ist eine einschränkende Spezialisierung des Typs int
-128, ...-1, 0, 1, ... 127
Wertebereich: -27 <= byte <= 27-1
byte ist eine einschränkende Spezialisierung des Typs short
...-1, 0, 1, ...
Wertebereich: entspricht der mathematischen Menge der ganzen Zahlen (Z)
integer ist eine einschränkende Spezialisierung des Typs decimal
1, 2, ...
Wertebereich: entspricht der mathematischen Menge der natürlichen Zahlen (N)
positiveInteger ist eine einschränkende Spezialisierung des Typs nonNegativeInteger
... -2, -1
Wertebereich: {..., -2, -1}, die unendliche Menge der negativen Zahlen
negativeInteger ist eine einschränkende Spezialisierung des Typs nonPositiveInteger
0, 1, 2, ...
Wertebereich: 0 <= nonNegativeInteger
nonNegativeInteger ist eine einschränkende Spezialisierung des Typs integer
... -2, -1, 0
Wertebereich: {..., -2, -1, 0} die unendliche Menge der negativen Zahlen, und die Null
nonPositiveInteger ist eine einschränkende Spezialisierung des Typs integer
0, 1, ... 18446744073709551615
Wertebereich: 0 <= unsignedLong <= 264-1
unsignedLong ist eine einschränkende Spezialisierung des Typs nonNegativeInteger
0, 1, ...4294967295
Wertebereich: 0 <= unsignedInt <= 232-1
unsignedInt ist eine einschränkende Spezialisierung des Typs unsignedLong
0, 1, ... 65535
Wertebereich: 0 <= unsignedShort <= 216-1
unsignedShort ist eine einschränkende Spezialisierung des Typs unsignedInt
0, 1, ... 255
Wertebereich: 0 <= unsignedByte <= 28-1
unsignedByte ist eine einschränkende Spezialisierung des Typs unsignedShort
-1E4, 1267.43233E12, 12.78e-2, 12, INF
32-Bit-Zahl mit einfacher Genauigkeit gemäß IEEE 754-1985.
Wertebereich: m * 2e, wobei m und einteger-Elemente mit m <= 224, und -149 <= e < 104 sind.
-1E4, 1267.43233E12, 12.78e-2, 12, INF
64-Bit-Zahl mit doppelter Genauigkeit gemäß IEEE 754-1985.
Wertebereich: m * 2e, wobei m und einteger-Elemente mit m <= 253, und -1075 <= e < 970 sind.
true, false, 1, 0
Unterstützung der klassischen zweiwertigen Logik
13:20:00-05:00, 13:20:00.000
Uhrzeit, die täglich wiederkehrt, ausgedrückt im Format gemäß ISO 8601
2004-06-11
Datumsformat: CCYY-MM-DD, gemäß ISO 8601
1999, 2001, 2004
Darstellung von Jahren des gregorianischen Kalenders gemäß ISO 8601
2004-06
Darstellung eines Monats eines bestimmten Jahres des gregorianischen Kalenders gemäß ISO 8601
----05, ----31
Darstellung eines wiederkehrenden Tages eines Monats gemäß ISO 8601
--31-12, --01-01
Darstellung eines wiederkehrenden gregorianischen Datums, gebildet aus Tag Monat und Monat im Format --MM-DD, gemäß ISO 8601
--03, --12
Monatsformat: --MM-- gemäß ISO 8601
2004-06-11T07:12:46.000+02:00
Zeitpunkt, ausgedrückt durch Datum und Uhrzeit; beide gemäß ISO 8601 codiert.
P1Y2M3DT10H30M12.3S
Zeitraum von einem Jahr, zwei Monaten, drei Tagen, zehn Stunden, 30 Minuten und 12,3 Sekunden
Nach Größe (Signifikanz) geordnete Koordinate im sechs-dimensionalen Raum aus Jahr, Monat, Tag, Stunde, Minute und Sekunde.
Formatdefinition laut ISO 8601
SGVsbG8gd29ybGQhCg==
Base64-Darstellung eines beliebigen Binär-interpretierten Inhaltes gemäß IETF RFC 2045
0FB7
Hexadezimale Darstellung beliebiger Binär-interpretierter Inhalte
http://www.jeckle.de
Jede gemäß IETF RFC 2396 bzw. IETF RFC 2732 gültige URI
en-GB, en, de-de
Sprachcodierung gemäß IETF RFC 1766 und XML Recommendation language identification.
Die Identifikationsnamen werden durch ISO 639 sowie ISO 3166 definiert.
language ist eine einschränkende Spezialisierung des Typs token
test, XYZ
XSD-Darstellung des DTD-Typen ID.
Zugelassen sind alle Ausprägungen der Namespaceproduktion 4 (NCName).
ID ist eine einschränkende Spezialisierung des Typs NCName
test, XYZ
XSD-Darstellung des DTD-Typen IDREF.
Zugelassen sind alle Ausprägungen der Namespaceproduktion 4 (NCName).
IDREF ist eine einschränkende Spezialisierung des Typs NCName
test1 test2 test4, test3 test5
XSD-Darstellung des DTD-Typen IDREFS.
Zugelassen sind Listen aus white space separierten Ausprägungen der Namespaceproduktion 4 (NCName).
IDREFS ist eine nichtleere Aufzählung von IDREF-Ausprägungen
XSD-Darstellung des DTD-Typen ENTITY.
Zugelassen sind alle Satzformen, die der Produktion NCName der XML-Namensräume entsprechen und als ungeparste Entität definiert sind.
ENTITY ist eine einschränkende Spezialisierung des Typs NCName
XSD-Darstellung des DTD-Typen ENTITIES.
Zugelassen sind Listen aus white space separierten Ausprägungen des Typs ENTITY.
ENTITIES ist eine nichtleere Aufzählung von ENTITY-Ausprägungen
XSD-Darstellung des DTD-Typen NOTATION.
Zur Verwendung dieses Typs in einem Schema muß eine Ableitung von NOTATION durch den Anwender definiert werden.
US, Deutschland
XSD-Darstellung des DTD-Typen NMTOKEN.
Ausprägungen dieses Typs müssen konform zur Produktion 7 der XML-Spezifikation sein.
NMTOKEN ist eine einschränkende Spezialisierung des Typs token
US UK Aus, Ger
XSD-Darstellung des DTD-Typen NMTOKENS.
Zugelassen sind Listen aus white space separierten Ausprägungen des Typs NMTOKEN.
NMTOKENS ist eine nichtleere Aufzählung von NMTOKEN-Ausprägungen
1, 2.3, aGVsb, 06b8f45, test&#20;für&#20;anyType&#0A; <sentence>the quick brown <animal>fox</animal>...</sentence>
Allgemeinster Datentyp. Konzeptionell bildet er die Vereinigung aller angebotenen XSD-Typen.


Die einfachste Form zur Definition eines Elements mit unstrukturiertem typisierten Inhalt lautet:

<xsd:element
                    name="elementName"
                    type="typeName"/> 

In dieser Darstellung entspricht die Definition -- von der Typisierung abgesehen -- der Mächtigkeit der ELEMENT-Deklaration einer DTD mit PCDATA-artigem Inhalt.
XSD definiert ferner folgende Charakteristika für Elemente, die durch Attribute der Elementdeklaration ausgedrückt werden:

Nachfolgend sind einige Elementdeklarationen für unstrukturierten Inhalt versammelt

Beispiel 2:
Beispiel 29:
(1)<element name="geburtsdatum" type="xsd:date"/> 
(2)<element name="pi" 
(3)	type="xsd:double" 
(4)	fixed="3.141592653" 
(5)	block="#all" 
(6)	final="#all"/> 
(7)<element name="vorname" 
(8)	type="xsd:token" 
(9)	minOccurs="1" 
(10)	maxOccurs="unbounded"/> 
(11)<element name="artikelNummer" 
(12)	type="xsd:NCName" 
(13)	form="qualified"/>


Die Deklaration geburtsdatum definiert ein XML-Element des Typs date zur Darstellung eines Datums. Weitere Festlegungen sind nicht getroffen, daher wird das Element mit minOccurs und maxOccurs 1 belegt, wodurch es als zwingend anzugebend (mandatory) und skalar (d.h. nicht mengenwertig) ausgewiesen wird.
pi legt die gleichnamige mathematische Konstante fest. Als Datentyp wurde double, eine Gleitkommazahl mit doppelter Genauigkeit gewählt. Als konstante Belegung wird durch das fixed Attribut der entsprechende Zahlenwert festgelegt. Daher muß eine Vorgabebelegung durch das Attribut default nicht erfolgen; gemäß Schema-Spezifikation darf sie sogar nicht erfolgen, fixed und default schließen sich gegenseitig aus. Um eine weitere Spezialisierung des Elements durch Vererbung oder Aggregation zu verhindern wird der Wert von block auf #all gesetzt, wodurch die Teilnahme an allen Typbildungsmechanismen unterbunden wird.
Die Definition für vorname nutzt als Datentyp den token, der automatisch mehrfache, führende und abschließende Leerzeichen sowie sonstige Formatierungssymbole entfernt. Ferner kann dieses Element beliebig häufig auftreten -- maxOccurs ist daher auf unbounded gesetzt. Die Fixierung der minimalen Auftrittshäufigkeit auf 1 (minOccurs) entspricht der Vorgabebelegung.
Für das Element artikelNummer ist als Typ NCName ausgewählt, was beliebigen Zeichenketten -- die keinen Doppelpunkt enthalten -- entspricht. Darüberhinaus ist das Attribut form mit dem Wert qualified versehen. Dies führt dazu, daß das Namensraumkürzel für dieses Element zwingend im Instanzdokument anzugeben ist.

Zur Umsetzung des freien Inhaltsmodells, das beliebige Inhalte aus den definierten Elementen und freien Texten zuläßt, wird ebenfalls auf das Typsystem zurückgegriffen.
Wird das type Attribut nicht belegt, so wird gemäß Vorgabe der Typ anyType angenommen. Elemente dieses Typs können beliebige wohlgeformte Inhalte beherbergen.
Die beiden nachfolgenden Angaben sind daher äquivalent.

<element
   name="elementName"
   type="xsd:anyType/>
<element name="elementName"/>

XSD prägt den bereits im Kontext der DTD genutzten Typbegriff strenger. Dies zeigt sich deutlich in der Existenz des XSD-Elements complexType. Es führt die Möglichkeit einer expliziten, d.h. von der Verwendung losgelösten Typbildung, ein. Syntaktisch kann die complexType-Definition sowohl innerhalb einer Elementdefinition, als auch separat erfolgen.
Den einfachsten Anwendungsfall bildet die eingebettete leere complexType-Definition zur Darstellung des leeren Inhaltsmodells.
Die Syntax hierfür lautet (der XSD-Namensraum sei an das Präfix xsd gebunden):

<xsd:element
   name="elementName">
   <xsd:complexType/>
</xsd:element>

Ein XML-Schema-validierender Parser verhält sich in diesem Falle identisch zu einem (DTD-)validierenden Parser für das Inhaltsmodell EMPTY. Daher werden für die obige Festlegung ausschließlich die beiden Darstellungsformen zur Angabe eines leeren Elements (<elementName/> bzw. <elementName></elementName>) akzeptiert.

Die Befüllung des complexType-Elements leitet direkt zum wichtigsten Inhaltsmodell über, dem explizit angegebener Kindelemente.
Während die DTD das sequentielle Auftreten der Kindelemente in der angegebenen Reihenfolge nur implizit zu Grunde legt, stellt XML-Schema diesen Sachverhalt durch ein eigenes Sprachkonstrukt klar dar. Hierfür werden alle Kindelemente in ein weiteres Element sequence eingebettet.
Das Auswahlinhaltsmodell (auch: Selektionsmodell) -- in der DTD durch Oder-Verknüpfung der einzelnen Elemente einer Elementgruppe ausgedrückt (...|...|...) -- wird entsprechend durch das XSD-Element choice ausgedrückt.
Eine besondere Variante des Selektionsmodells stellt die all-Gruppe dar. Sie kürzt das häufig genutzte Inhaltsmodell (...|...|...)* ab. Es erlaubt die Angabe der Kindelemente in beliebiger Reihenfolge.
In Entsprechung zur Klammerdarstellung in der DTD muß zwingend einer der drei Reihenfolgetypen sequence, choice oder all als Element spezifiziert werden.
Analog der Klammer-Schachtelung in der DTD, können auch die verschiedenen Modellgruppen ineinander kombiniert werden.
Am Beispiel der Elementdefinitionen der Projektverwaltung:

Beispiel 3: Einige Elementdefinitionen
Beispiel 30: Einige Elementdefinitionen
(1)<?xml version = "1.0" encoding = "UTF-8"?>
(2)<xsd:schema xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
(3)	<xsd:element name = "ProjektVerwaltung">
(4)		<xsd:complexType>
(5)			<xsd:sequence>
(6)				<xsd:element ref = "Person" maxOccurs = "unbounded"/>
(7)				<xsd:element ref = "Projekt" maxOccurs = "unbounded"/>
(8)			</xsd:sequence>
(9)		</xsd:complexType>
(10)	</xsd:element>
(11)	<xsd:element name = "Person">
(12)		<xsd:complexType>
(13)			<xsd:sequence>
(14)				<xsd:element name = "Vorname" type = "xsd:token" maxOccurs = "unbounded"/>
(15)				<xsd:element name = "Nachname" type = "xsd:token"/>
(16)				<xsd:element ref = "Qualifikationsprofil" minOccurs = "0"/>
(17)			</xsd:sequence>
(18)		</xsd:complexType>
(19)	</xsd:element>
(20)	<xsd:element name = "Projekt">
(21)		<xsd:complexType/>
(22)	</xsd:element>
(23)	<xsd:element name = "Qualifikationsprofil">
(24)		<xsd:complexType mixed = "true">
(25)			<xsd:sequence>
(26)				<xsd:element name = "Qualifikation" type = "xsd:string" minOccurs = "0" maxOccurs = "unbounded"/>
(27)				<xsd:element name = "Leistungsstufe" type = "xsd:string" minOccurs = "0" maxOccurs = "unbounded"/>
(28)			</xsd:sequence>
(29)		</xsd:complexType>
(30)	</xsd:element>
(31)</xsd:schema>
Download des Beispiels


Das Schema enthält alle Elementdefinitionen für die Projektverwaltung. Innerhalb jedes element-Elements sind die entsprechenden Kindelemente in sequence-Strukturen eingebettet. Analog dem entsprechenden DTD-Mechanismus müssen sie daher in der Reihenfolge ihres Auftretens im Schema auch im Instanzdokument wiedergegeben werden.
Von besonderem Interesse ist die Definition des Qualifikationsprofils. Es handelt sich dabei um ein mixed content model, ausgedrückt durch das Boole'sche Attribut mixed (in Spezifikation nachschlagen). Die dargestellte Definition läßt an dieser Stelle einen weiteren Vorteil der Schemasprache gegenüber der Dokument-Typ-Definition offensichtlich werden. Während gemischte Inhalte aus Auszeichnungssymbolen und freiem Text durch DTD-validierende Parser nur rudimentär geprüft werden konnten, ermöglicht XSD die vollständige inhaltliche Validierung gemischter Inhalte. Die lediglich partielle Strukturvalidierung der DTD lag in deren syntaktischer Konstruktion zur Darstellung gemischter Inhalte begründet. Diese erlaubt zwar die Spezifikation von innerhalb unstrukturierter Textpassagen (möglicherweise) auftretenden Elementen, nicht jedoch die Überwachung der Auftrittshäufigkeit oder Reihenfolge. So wäre gemäß der Beispiel-DTD auch die Hintereinanderreihung von Qualifikationen ohne zugehörige Leistungsstufe zulässig. Insgesamt kann durch DTD-basierte Validierung das Auftreten von Elementen in gemischten Inhaltsmodellen nicht geprüft werden. Durch den Einsatz von XML-Schema ergibt sich auch für mixed content models die Möglichkeit zur strikten Validierung. Dies bedeutet konkret die Prüfbarkeit der Anzahl und Auftretensreihenfolge der angegebenen Kindelemente (in Spezifikation nachschlagen).
Darüberhinaus enthält das Beispiel neben lokalen Elementdeklarationen, die sich vollständig im Elternelement finden (wie Vorname, Nachname und Qualifikation), auch globale Elementdeklarationen, die zunächst deklariert und in einem zweiten Schritt durch Referenzierung als Kindelemente verwendet werden (wie Person und Projekt innerhalb Projektverwaltung, oder Qualifikationsprofil innerhalb des Elements Person). Hierdurch können vollständige Elemente an verschiedenen Stellen im Schema referenziert und so verwendet werden. Die Definition ist der lokalen ebenbürtig und wird im Instanzdokument identisch behandelt. Zusammenfassend läßt sich festhalten: Mit dem Referenzierungsmechanismus für Elemente kann eine einfache Form der Wiederverwendung umgesetzt werden.
Den Zeichenketten-artigen Elementtypen wurde durchgehend der XSD-Typ string zugewiesen.

Durch die Referenzierungsmöglichkeit existiert eine erste Möglichkeit zur Wiederverwendung bereits im Schema definierter Elemente. Jedoch werden Elemente hierbei zwingend in ihrer vollständigen Definition, d.h. Name, Typ und Inhaltsmodell, eingebunden. Im Grunde genommen ist diese Art der Wiederverwendung bereits mit den Mitteln der DTD möglich. Allerdings, wie im eben betrachteten Beispiel, auch dergestalt, daß nur die vollständige Definition übernommen werden kann.
XML-Schema bietet zusätzlich die Möglichkeit, strukturierte Typen, die ausschließlich durch ihr Inhaltsmodell definiert werden, festzulegen. In der Konsequenz verändert sich der durch die DTD formulierte Typbegriff hin zu einer eher an den Programmiersprachen orientierten Sichtweise, da die Benennung des Typs von der Namensgebung der typisierten Instanz separiert wird.
Syntaktisch erfolgt die Typbildung durch die Benennung des complexType-Elements durch ein Attribut name. Um die mehrfache Verwendung eines solchen Typen zu ermöglichen, muß seine Definition zwingend auf einer Baumstufe erfolgen, die für alle nutzenden Elemente erreichbar ist. Üblicherweise werden daher diese Definitionen auf der ersten Stufe, direkt unterhalb des Wurzelknotens, plaziert.
Zur Unterscheidung dieser benannten komplexen Typen werden die bisher genutzten -- namenlosen Typen -- als anonyme komplexe Typen bezeichnet.
Das nachfolgende Beispiel zeigt die Definition eines benannten komplexen Typen am Beispiel des Elements Person:

Beispiel 4: Nutzung benannter komplexer Typen
Beispiel 31: Nutzung benannter komplexer Typen
(1)<xsd:schema xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
(2)   <xsd:complexType name="PersonType">
(3)	   <xsd:sequence>
(4)	   <xsd:element name = "Vorname" type = "xsd:string" 
(5)	                   maxOccurs = "unbounded"/>
(6)	   <xsd:element name = "Nachname" type = "xsd:string"/>
(7)	   <xsd:element ref = "Qualifikationsprofil" minOccurs = "0"/>
(8)   </xsd:sequence>
(9)   </xsd:complexType>
(10)   
(11)   <xsd:element name = "ProjektVerwaltung">
(12)      <xsd:complexType>
(13)         <xsd:sequence>
(14)            <xsd:element name="Person" type="PersonType" maxOccurs = "unbounded"/>
(15)            <xsd:element ref = "Projekt" maxOccurs = "unbounded"/>
(16)         </xsd:sequence>
(17)      </xsd:complexType>
(18)   </xsd:element>
(19)
(20)   <xsd:element name = "Projekt">
(21)      <xsd:complexType/>
(22)   </xsd:element>
(23)
(24)   <xsd:element name = "Qualifikationsprofil">
(25)      <xsd:complexType mixed = "true">
(26)         <xsd:sequence>
(27)            <xsd:element name = "Qualifikation" type = "xsd:string" 
(28)                            minOccurs = "0" maxOccurs = "unbounded"/>
(29)            <xsd:element name = "Leistungsstufe" type = "xsd:string" 
(30)                            minOccurs = "0" maxOccurs = "unbounded"/>
(31)         </xsd:sequence>
(32)      </xsd:complexType>
(33)   </xsd:element>
(34)</xsd:schema>
Download des Beispiels


Das Schema zeigt die Definition des komplexen Typen PersonType. Dieser Typ wird zur Festlegung des Inhaltsmodells des Elements Person verwendet.

Definition eigener Datentypen durch Vererbung:
Zur Unterstützung von Wiederverwendung und Erhöhung der Strukturierung des Entwurfs definiert XSD ein Vererbungskonstrukt zur Bildung neuer komplexer Typen auf der Basis bereits bestehender.
Zwei verschiedene Ableitungssemantiken werden angeboten:

Das nachfolgende Beispiel zeigt die Anwendung der einschränkenden Ableitung.
Hierbei erbt der benannte komplexe Typ childType von parentType. Innerhalb des -- aus syntaktischen Gründen notwendigen -- Elements complexContent findet sich die Definition der Vererbung im Element restriction, das base-Attribut verweist auf den benannten Elterntypen.
Der Inhalt des restriction-Elements gleicht der Inhaltsmodelldefinition des komplexen Typen: Auch hier werden Elemente und ihre Auftrittsstruktur (im betrachteten Beispiel sequence) angegeben. Die Elementdefinition des Elements elementA in childType schränkt die gleichnamige Elementdefinition innerhalb des Elterntypen ein. Nachvollziehbar wird diese Einschränkungsbeziehung zwischen short und int bei Betrachtung der Datentyphierarchie und der Typdefinition der verwendeten Primitivtypen. So bildet short per definitionem eine eingeschränkte Untermenge von int an. (Die entsprechende XSD-Definition findet sich im Schema für Schema).
Die beiden Elementdefinitionen usage1 und usage2 zeigen die Verwendung der anwenderdefinierten Typen.

Beispiel 5: Einschränkende Typableitung
Beispiel 32: Einschränkende Typableitung
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
(3)<xsd:complexType name="parentType">
(4)	<xsd:sequence>
(5)		<xsd:element name="elementA" type="xsd:int"/>
(6)	</xsd:sequence>
(7)</xsd:complexType>
(8)
(9)<xsd:complexType name="childType">
(10)<xsd:complexContent>
(11)	<xsd:restriction base="parentType">
(12)		<xsd:sequence>
(13)			<xsd:element name="elementA" type="xsd:short"/>
(14)		</xsd:sequence>
(15)	</xsd:restriction>
(16)</xsd:complexContent>
(17)</xsd:complexType>
(18)
(19)<xsd:element name="usage1" type="parentType"/>
(20)<xsd:element name="usage2" type="childType"/>
(21)
(22)</xsd:schema>
Download des Beispiels


Durch das strukturierte Inhaltsmodell ergeben sich über die reine Typisierung hinausgehende Möglichkeiten zur Einschränkung der Inhalte. Die nachfolgende Tabelle stellt einige Varianten zusammen.

Tabelle  6: Beispiele für zulässige Restriktionen
Tabelle 6: Beispiele für zulässige Restriktionen
Basistyp
Restriktion
Bemerkung
Zusätzliche Belegung eines Elements mit einem Vorgabewert
Beschränkung eines zunächst frei wählbaren Elements auf konstanten Inhalt
Definition eines Typen für ein zunächst untypisiertes Element.
(Auch hierbei handelt es sich um eine einschränkende Redefinition, da allen Elementen ohne Typdefinition standardmäßig der Typ anyType zugeordnet wird.)
minOccurs=n2, maxOccurs=m2
Restriktion der Auftrittshäufigkeit auf eine geringere Anzahl.
Daher gilt: n1 <= n2 und m1 >= m2


Die direkte Umkehrung der einschränkenden Spezialisierung bildet die erweiternde Spezialisierung. Sie greift nicht verändernd auf die Elemente des Supertyps zu, sondern definiert zusätzliche neue.
Untenstehendes XSD-Schema zeigt dies am Beispiel des Supertyps parentElement, der durch das abgeleitete Kindelement childElement erweitert wird. Hierzu definiert childElement ein zusätzliches elementB.

Beispiel 6: Erweiternde Typableitung
Beispiel 33: Erweiternde Typableitung
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
(3)	<xsd:complexType name="parentElement">
(4)		<xsd:sequence>
(5)			<xsd:element name="elementA"/>
(6)		</xsd:sequence>
(7)	</xsd:complexType>
(8)	
(9)	<xsd:complexType name="childElement">
(10)		<xsd:complexContent>
(11)			<xsd:extension base="parentElement">
(12)				<xsd:sequence>
(13)					<xsd:element name="elementB"/>
(14)				</xsd:sequence>
(15)			</xsd:extension>		
(16)		</xsd:complexContent>
(17)	</xsd:complexType>
(18)</xsd:schema>
Download des Beispiels


Zusätzlich sieht XML Schema die Möglichkeit vor, komplexe Typen von simplen abzuleiten. Dies mag auf den ersten Blick ungewöhnlich erscheinen, eröffnet es doch scheinbar einen Weg, unstrukturierte Typen in strukturierte zu überführen.
Bei näherer Betrachtung offenbart sich jedoch, daß hier lediglich der Ableitungsbegriff überladen wurde, um einen einfachen Weg zur Verknüpfung der beiden Inhaltsmodelle strukturierter „XML-artiger“ Inhalt -- wie er durch complexTypes repräsentiert wird -- auf der einen, und unstrukturierter Inhalt -- wie er durch die einfachen Datentypen repräsentiert wird -- auf der anderen Seite, zu erhalten.

Beispiel 7: Ableitung eines komplexen Typen von einem Simplen
Beispiel 34: Ableitung eines komplexen Typen von einem Simplen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xs:schema 
(3)	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
(4)	elementFormDefault="qualified" 
(5)	attributeFormDefault="unqualified">
(6)	<xs:element name="Vorname">
(7)		<xs:complexType>
(8)			<xs:simpleContent>
(9)				<xs:extension base="xs:string">
(10)					<xs:attribute 
(11)						name="rufname" 
(12)						type="xs:boolean"/>
(13)				</xs:extension>
(14)			</xs:simpleContent>
(15)		</xs:complexType>
(16)	</xs:element>
(17)</xs:schema>
Download des Beispiels


Durch die im Beispiel dargestellte Syntax wird es ermöglicht unstrukturiert-getypten Elementen Attribute zuzuordnen, obwohl diese eigentlich Bestandteil der Definition komplex-getyper Elemente sind.

So wird im Beispiel dem Element Vorname sowohl der simple Typ string, als auch durch den Ableitungsmechanismus das Attribut rufname -- im Rahmen eines complexType, zugeordnet.
Die Typisierung des Elements erfolgt hierbei nicht durch das type-Attribut innerhalb der Elementdeklaration, sondern innerhalb der simpleContent-Festlegung.

Neben der anwenderdefinierten Bildung komplexer Typen steht es dem XSD-Modellierer auch offen, eigene (primitive) Datentypen festzulegen oder eigene Typen von bestehenden abzuleiten.
Hierfür definiert XML-Schema Part1 das Element simpleType. Für einfache Typen ist jedoch nur die einschränkende Vererbung (restriction) zugelassen. Dies liegt in der praktischen Beherrschbarkeit des Typsystems begründet. Durch die strikte Restriktionssemantik ergibt sich die Möglichkeit kontravarianter Substitution, wie sie bei objektorientierten Typsystemen und Vererbungsstrukturen anzutreffen ist. Dies bedeutet, daß an jeder Stelle, an der eine Ausprägung eines Supertyps erwartet wird, auch -- unter Erhalt der Typrestriktion -- eine Ausprägung eines Subtypen auftreten darf. Beispielhaft: Wird an einer Stelle des Instanzdokumentes durch das Schema das Auftreten einer Ausprägung von integer verlangt, so kann der Anwender auch Ausprägungen der Subtypen int, short oder byte angeben ohne die Gültigkeit des XML-Dokuments zu beeinträchtigen.

Vereinigungstypen werden aus einer nichtleeren Menge von Ausgangstypen gebildet.
Das Beispiel zeigt die Definition eines Typen termin, der den vorgegebenen Primitivtypen date und eine Liste NamenDerWochentage (deren Definition nicht dargestellt ist) vereinigt. Insbesondere zeigt der Ausschnitt die Möglichkeit der Vereinigungsbildung auch über aggregierte Typen.

(1)<xs:simpleType name="termin">
(2)	<xs:union memberTypes="xs:date NamenDerWochentage"/>
(3)</xs:simpleType>

Das XSD-Beispiel zeigt, als Fragment der XML-Schemaspezifikation, die Definition des vorgegebenen Typs short, einer einschränkenden Spezialisierung des Typs int.
Am Beispiel gut nachvollziehbar sind die beiden Schritte zur Bildung eines eigenen Typen:

  1. Auswahl eines Ausgangstypen (später Elementtyp (bei aggregierten Typen) oder Basistyp (bei abgeleiteten Typen) )
  2. Typdefinition durch Anwendung der entsprechenden Typkonstruktion und evtl. Einschränkung verschiedener Charakteristika

Im Beispiel wird der kleinste und größte gültige Wert (minInclusive bzw. maxInclusive) des neuen Typen short gegenüber dem Basistypen beschränkt.

Beispiel 8: Einschränkende Spezialisierung eines simplen Typen
Beispiel 35: Einschränkende Spezialisierung eines simplen Typen
(1)<xsd:simpleType name="short" id="short">
(2)	<xsd:restriction base="xsd:int">       
(3)		<xsd:minInclusive value="-32768" 
(4)			id="short.minInclusive"/>       
(5)		<xsd:maxInclusive value="32767" 
(6)			id="short.maxInclusive"/>    
(7)	</xsd:restriction> 
(8)</xsd:simpleType>


Die Bildung aggregierter Typen folgt demselben Muster. Jedoch tritt an die Stelle der Ableitung die Spezifikation des Aggregationstyps (im Beispiel Liste) und Angabe des Inhaltstyps (im Beispiel string).

Beispiel 9: Bildung eines Aggregationstypen
Beispiel 36: Bildung eines Aggregationstypen
(1)<xsd:simpleType name="WarenkorbElemente">
(2)	<xsd:list itemType="xsd:string"/>
(3)</xsd:simpleType>


Nachfolgend sind die verschiedenen Beschränkungsmöglichkeiten zusammengefaßt:



Definition von Attributen:
Die Attributdeklaration erfolgt durch das XSD-Element attribute. Die Mächtigkeit entspricht auch hier, wie bereits für die Elemente verwirklicht, einer Obermenge der DTD. So können neben optionalen, zwingenden und konstanten Attributen auch Aufzählungsattribute und Mengen realisiert werden. Hierbei wurde auf die Orthogonalität zum durch simpleType geschaffenen Typmechanismus geachtet.
Die Charakteristika (ausgedrückt in Attributen des XSD-Elements attribute) einer Attributdeklaration umfassen:

Anmerkung: Einen Anwendungsfall der Belegung prohibited für use bilden Attribute, die innerhalb des Schemas bereits definiert sind, jedoch noch nicht zur allgemeinen Nutzung freigegeben wurden.

Beispiel 10: Einige Attributdefinitionen
Beispiel 37: Einige Attributdefinitionen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
(3)	<xsd:attribute name="myAtt1"/>
(4)	
(5)	<xsd:attribute name="myAtt2" type="xsd:decimal"/>
(6)	
(7)	<xsd:attribute name="myAtt3">
(8)		<xsd:simpleType>
(9)			<xsd:restriction base="xsd:int">
(10)				<xsd:minInclusive value="10"/>
(11)				<xsd:maxInclusive value="20"/>
(12)			</xsd:restriction>
(13)		</xsd:simpleType>
(14)	</xsd:attribute>
(15)	
(16)	<xsd:simpleType name="myType1">
(17)		<xsd:restriction base="xsd:string">
(18)			<xsd:maxLength value="5"/>
(19)		</xsd:restriction>
(20)	</xsd:simpleType>
(21)	<xsd:attribute name="myAtt4" type="myType1"/>
(22)	
(23)	
(24)	
(25)	<xsd:element name="foo">
(26)		<xsd:complexType>
(27)			<xsd:attribute ref="myAtt1" use="optional"/>
(28)			<xsd:attribute ref="myAtt2" use="required"/>
(29)			<xsd:attribute ref="myAtt3" use="prohibited"/>
(30)			<xsd:attribute ref="myAtt4"/>
(31)			<xsd:attribute name="myAtt5" type="xsd:date" id="myDate"/>
(32)			<xsd:attribute name="myAtt6">
(33)				<xsd:simpleType>
(34)					<xsd:restriction base="xsd:float">
(35)						<xsd:totalDigits value="5"/>
(36)					</xsd:restriction>
(37)				</xsd:simpleType>
(38)			</xsd:attribute>
(39)		</xsd:complexType>
(40)	</xsd:element>	
(41)
(42)</xsd:schema>
Download des Beispiels


Das Beispiel zeigt einige Varianten der Attributdeklaration. So definieren myAtt1 mit myAtt4 globale Attribute, die innerhalb verschiedener Elemente verwendet werden können. Hierdurch wird die bereits für Elemente verwirklichte Mimik der einmaligen Deklaration und anschließenden beliebigen Verwendung auch auf Attribute ausgedehnt. Die Nutzung der so deklarierten Attribute geschieht durch das ref-Attribut innerhalb des Attribute-Elements des beherbergenden Elements.
myAtt1 definiert ein typenloses Attribut, dem vorgabegemäß der allgemeinste Typ anyType zugeordnet wird. Die Angabe dieses Attributes ist optional (use="optional"), was der Vorgabe entspricht.
Der XSD-Standardtyp decimal findet zur Definition des Attributs myAtt2 Verwendung. Die zwingend anzugebenden (use="required") Inhalte dieses Attributs werden durch einen XML-Schema-Parser auf Typkonformität geprüft.
myAtt3 veranschaulicht die Bildung eines anonymen (inneren) atomaren Typen zur Definition eines Attributs. Der durch Restriktion gebildete neue Datentyp steht ausschließlich innerhalb des Attributs myAtt3 zur Verfügung. Die Syntax der Datentypspezialisierung entspricht der im vorhergehenden Abschnitt diskutierten. Zudem ist die Verwendung des Attributes innerhalb eines XML-Dokumentes untersagt; ausgedrückt durch die Belegung use="prohibited"
Analog der Typisierung eines Elementinhaltes durch einen anwenderdefinierten Typen gestaltet sich das Vorgehen für Attribute. Veranschaulicht wird dies durch die Definition von myAtt4. Sie greift auf den eigen-definierten Typen myType1 zurück.
Dem Attribut myAtt5 ist zusätzlich zur Benennung, die innerhalb des verwendenden Elementes eindeutig sein sollte, ein Dokument-weiter Schlüssel (id) zugeordnet.
Innerhalb des Elements foo werden die fünf zuvor definierten Attribute verwendet. Trotz der Reihenfolge der Definitionen im complexType-Element verfügen die Attribute im XML-Instanzdokument -- auch bei der Verwendung von XML-Schema -- über keinerlei Reihenfolge (vgl. XML-Spezifikation).
Zusätzlich enthält die Elementdefintion für foo mit myAtt6 ein „lokales“ Attribut. Diese Definitionsvariante entspricht am ehesten der der Document Type Definition, da sie eine Wiederverwendung außerhalb des definierenden Elements ausschließt.

Beispiel 11: Vollständiges XML-Schema der Projektverwaltung
Beispiel 38: Vollständiges XML-Schema der Projektverwaltung
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
(3)	<xsd:element name="Nachname" type="xsd:string"/>
(4)	<xsd:complexType name="PersonType">
(5)		<xsd:sequence>
(6)			<xsd:element ref="Vorname" maxOccurs="unbounded"/>
(7)			<xsd:element ref="Nachname" maxOccurs="unbounded"/>
(8)			<xsd:element name="Qualifikationsprofil" type="QualifikationsprofilType" minOccurs="0"/>
(9)		</xsd:sequence>
(10)		<xsd:attribute name="PersID" type="xsd:ID" use="required"/>
(11)		<xsd:attribute name="Gehaltsgruppe" default="1a">
(12)			<xsd:simpleType>
(13)				<xsd:restriction base="xsd:NMTOKEN">
(14)					<xsd:enumeration value="1"/>
(15)					<xsd:enumeration value="1a"/>
(16)					<xsd:enumeration value="2"/>
(17)				</xsd:restriction>
(18)			</xsd:simpleType>
(19)		</xsd:attribute>
(20)		<xsd:attribute name="mitarbeitInProjekt" type="xsd:IDREFS" use="required"/>
(21)	</xsd:complexType>
(22)	<xsd:complexType name="ProjektType">
(23)		<xsd:attribute name="ID" type="xsd:ID" use="required"/>
(24)		<xsd:attribute name="date" type="xsd:date"/>
(25)		<xsd:attribute name="budget" default="10000.00">
(26)			<xsd:simpleType>
(27)				<xsd:restriction base="xsd:double">
(28)					<xsd:fractionDigits value="2"/>
(29)				</xsd:restriction>
(30)			</xsd:simpleType>
(31)		</xsd:attribute>
(32)		<xsd:attribute name="Projektleiter" type="xsd:IDREF" use="required"/>
(33)		<xsd:attribute name="Mitarbeiter" type="xsd:IDREFS" use="required"/>
(34)	</xsd:complexType>
(35)	<xsd:element name="ProjektVerwaltung">
(36)		<xsd:complexType>
(37)			<xsd:sequence>
(38)				<xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/>
(39)				<xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/>
(40)			</xsd:sequence>
(41)			<xsd:attribute name="version" type="xsd:string" fixed="1.0"/>
(42)		</xsd:complexType>
(43)	</xsd:element>
(44)	<xsd:complexType name="QualifikationsprofilType" mixed="true">
(45)		<xsd:choice minOccurs="0" maxOccurs="unbounded">
(46)			<xsd:element ref="Qualifikation"/>
(47)			<xsd:element ref="Leistungsstufe"/>
(48)			<xsd:any namespace="http://www.w3.org/1999/xhtml"/>
(49)		</xsd:choice>
(50)	</xsd:complexType>
(51)	<xsd:element name="Qualifikation" type="xsd:string"/>
(52)	<xsd:element name="Leistungsstufe" type="xsd:string"/>
(53)	<xsd:element name="Vorname" type="xsd:string"/>
(54)</xsd:schema>
Download des Beispiels


Abschließend eine gültige (sowohl valid als auch schema valid) Dokumentinstanz der Projektverwaltungsstruktur.

Beispiel 12: Gültiges Projektverwaltungsdokument
Beispiel 39: Gültiges Projektverwaltungsdokument
(1)<?xml version="1.0" encoding="ISO-8859-1"?>
(2)<ProjektVerwaltung
(3)	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
(4)	xsi:noNamespaceSchemaLocation="http://www.jeckle.de/vorlesung/xml/examples/projektverwaltung.xsd">
(5)	<Person PersID="Pers01" mitarbeitInProjekt="Prj01">
(6)		<Vorname>Hans</Vorname>
(7)		<Nachname>Hinterhuber</Nachname>
(8)	</Person>
(9)	<Person PersID="Pers02" mitarbeitInProjekt="Prj02">
(10)		<Vorname>Franz</Vorname>
(11)		<Vorname>Xaver</Vorname>
(12)		<Nachname>Obermüller</Nachname>
(13)		<Qualifikationsprofil>
(14)     IT-Kompetenz verschiedene Betriebssysteme und <Leistungsstufe>professionelle</Leistungsstufe>
(15)			<Qualifikation>Programmierung</Qualifikation> verschiedener Programmiersprachen
(16)     <Qualifikation>Entwickler</Qualifikation> von 1988-1990
(17)     <Qualifikation>Projektleiterfunktion</Qualifikation> von 1990-93 im X42-Projekt in Abteilung AB&amp;C
(18)   </Qualifikationsprofil>
(19)	</Person>
(20)	<Person PersID="Pers03" mitarbeitInProjekt="Prj02">
(21)		<Vorname>Fritz</Vorname>
(22)		<Nachname>Meier</Nachname>
(23)	</Person>
(24)	<Projekt ID="Prj01" Projektleiter="Pers01" Mitarbeiter="Pers01"/>
(25)	<Projekt ID="Prj02" Projektleiter="Pers02" Mitarbeiter="Pers03"/>
(26)</ProjektVerwaltung>
Download des Beispiels


Werkzeuge:
Zwar existiert -- wie für alle XML-Dokumente -- die Möglichkeit, Dokument Typ Definitionen und XML-Schemata „per Hand“ mit einem Texteditor zu erstellen, jedoch ist dieses Vorgehen, insbesondere für umfangreiche XML-Vokabulare, zeitaufwendig und fehlerträchtig. Zusätzlich läßt die rein textuelle Formulierung die entstehenden Schemadokumente schnell unübersichtlich werden.
Inzwischen existieren einige gute DTD- und Schemaeditoren, die zumeist neben visueller Syntaxhervorhebung auch die kontextsensitive Editierung erlauben und so eine wesentliche Erleichterung der Schemaerzeugung bilden. Gleichzeitig bieten die meisten verfügbaren Werkzeuge dieser Klasse auch Möglichkeiten zur Validierung des erzeugten Schemas an.
Ergänzend wird vielfach auch eine graphische Repräsentation der DTD- oder XSD-Struktur angeboten.
Die Abbildungen zeigen Ansichten der Werkzeuge XML Authority bzw. XML Spy

XML Authority
XML Spy
XML Spy
Web-Referenzen 1: Weiterführende Links und Werkzeuge
Web-Referenzen 9: Weiterführende Links und Werkzeuge


1.6   XHTML -- XML und das Web

Die Verbindung zwischen der generischen Metasprache XML und dem World Wide Web datiert zurück bis vor die Entstehung der XML ...
Wie bereits im Eingangskapitel erwähnt, bildet die Hypertext Markup Language HTML die eigentliche Initialzündung des World Wide Web. Technisch ist sie als Anwendung der normierten generischen Metasprache SGML realisiert und kann heute als vermutlich bekannteste und verbreitetste Auszeichnungssprache überhaupt gelten.

Die Entwicklung der HTML in Bezug auf SGML und XML

Die Graphik faßt noch einmal die Beziehung von HTML und SGML zusammen, und schlägt eine Brücke in die XML-Welt.
Ursprünglich setzte Tim Berners-Lee das Ur-HTML 1989 als SGML-Anwendung durch Definition einer geeigneten (SGML-)Document Type Definition um (vgl. IETF RFC 1866). Zwar ähnelt die für HTML definierte Syntax der später für XML-Dokumente eingeführten, jedoch läßt sich an einigen Stellen (deutlich) die Abkunft von SGML ablesen. Dies wird insbesondere bei Syntaxkonstrukten offenkundig, die zwar in SGML erlaubt, jedoch in der später gebildeten Untermenge XML illegal sind. Die fehlenden schließenden Tags (beim img- oder br-Element) oder die gelockerte Attributsyntax (beim compact-Attribut des ul-Elements) können hierfür als bekannte Beispiele dienen.
Diese SGML-Sprachmittel werden entweder durch den Anwender vorgegeben (wie SHORTTAG = YES für das img-Element) oder sind inhärent zur Kompaktifizierung der Instanzstrukturen (wie die Attributminimierung) vorgegeben. Sie stellen einen Gutteil der Unübersichtlichkeit und Komplexität der Sprache SGML dar, da durch sie prinzipiell unterschiedliche Darstellungen identischer Bedeutung erlaubt werden. Als Resultat des sich (theoretisch) ergebenden Umsetzungsaufwandes realisieren HTML-Browser bis heute nicht die volle Mächtigkeit von SGML, die notwendig wäre um HTML korrekt zu interpretieren, sondern nur einen herstellerabhängigen Ausschnitt. Daher kommt es immer wieder zu sichtbaren Inkompatibilitäten der HTML-Interpretation verschiedener Web-Browser.
Zusätzlich haben die verschiedenen Hersteller im Laufe der Zeit den ursprünglichen HTML-Standard um eigene proprietäre Elemente erweitert. Naturgemäß werden diese neuen Elemente nur durch den Browser des jeweiligen Herstellers interpretiert; alle anderen Browser ignorieren die ihnen unbekannten Tags spezifikationsgemäß und zeigen stattdessen nur den Elementinhalt an.
Die nachfolgenden Graphiken zeigen dies an einem einfachen Beispiel:

Beispiel 4: Ein (höchst) inkompatibles HTML-Dokument
Beispiel 40: Ein (höchst) inkompatibles HTML-Dokument
(1)<html>  
(2)   <table rules=none>
(3)      <tr>
(4)         <td>x1</td>
(5)      <tr>
(6)         <td>x2
(7)      <tr>
(8)         <td>x3
(9)   </table>
(10)   <blink>blinkender Text (... im Netscape Navigator)</blink>
(11)   <hr color="86db7f">
(12)   <marquee>beweglicher Text (... im MS Internet Explorer)</marquee> 
Download des Beispiels


Darstellung im MS Internet Explorer
Darstellung im Netscape Navigator

Das dargestellte HTML-Dokument nutzt das in der HTML-Spezifikation ab der Version 3.2 vorgesehene rules-Attribut. Die Abbildungen zeigen jedoch, daß es nur durch den Internet Explorer ausgewertet und dargestellt wird.
Die Tabellendefinition nutzt in der wiedergegebenen Form die Freiheiten des HTML-Standards aus, und verzichtet weitestgehend auf schließende Tags. Beide Browser geben trotzdem die Struktur korrekt wieder.
Bei den drei abschließenden Elementen handelt es sich um herstellerspezifische Erweiterungen durch Netscape (blink) bzw. Microsoft (color-Attribut und marquee-Element).

Einerseits zur (Wieder-)Vereinheitlichung der inzwischen offen konkurrierenden HTML-Dialekte, andererseits zur leichteren technischen Umsetzbarkeit der HTML-Grammatik initiierte das World Wide Web Konsortium 1998 die XHTML-Aktivität, welche sich die Umsetzung von HTML als XML-Anwendung zum Ziel setzte.
Mit der Verabschiedung des HTML-Nachfolgers XHTML v1.0 im Januar 2000 wurde für die bis dato prominenteste Web-Sprache die Abkehr von SGML vollzogen. Im Kern stellt die neue Sprache die Reformulierung der letzten SGML-basierten HTML-Variante 4.01 in XML dar. Wie bereits die Ur-Sprache verwendet auch XHTML (zunächst) den Grammatikmechanismus der Document Type Definition und ist „äußerlich“ (d.h. bei Betrachtung der Instanzdokumente) nicht von der Vorgängersprache zu unterscheiden. Genaugenommen sind die angebotenen Minimierungsmöglichkeiten für SGML optional und müssen nicht zwingend genutzt werden. Daher ist weiterhin jedes gültige XHTML v1.0-Dokument ebenfalls konform zur HTML v4.01-Definition.

Nachfolgend sind die Änderungen an HTML zusammengetragen, welche zum XHTML-Standard führten:

Wird ein HTML-Dokument entsprechend modifiziert, so erhält man ein wohlgeformtes XML-Dokument. Wird zusätzlich die DOCTYPE-Deklaration angegeben, und so die XHTML-DTD referenziert, so kann zusätzlich die Gültigkeit sichergestellt werden.
Die aktuell verfügbaren Browser können überwiegend bereits XHTML v1.0-konforme Dokumente darstellen.
Im Detail bedeutet dies, daß neben der Einhaltung der durch die DTD definierten Strukturen auch die Nutzung des XHTML-Namensraumes für das gesamte Dokument erfolgen muß. Konsequenterweise muß jedes XHTML-Dokument ferner die entsprechende XHTML-DTD referenzieren. Zur korrekten Behandlung bereits existierender Dokument-Instanzen, die noch Elemente früherer HTML-Versionen beinhalten, welche nicht mehr durch den Standard unterstützt werden, sind insgesamt drei HTML-DTDs durch den Standard definiert. Neben den DTDs zur Darstellung Frame-basierter (frameset-DTD) bzw. „normaler“ (strict-DTD) Dokumente ermöglicht die transitional Dokument Typ Definition den leichteren Übergang zu XHTML.
Zur automatisierten Anpassung existierender HTML-Dokumente auf den neuen Sprachstandard hat das W3C das kostenfreie Werkzeug Tidy veröffentlicht.
Der nachfolgende XHTML-Code wurde mit diesem Werkzeug automatisch aus dem vorangegangenen Beispiel erzeugt. (Aufruf: tidy -asxml incompatibleHTML.html > validXHTML.html)

Beispiel 5: Ein einfaches XHTML-Dokument
Beispiel 41: Ein einfaches XHTML-Dokument
(1)<?xml version="1.0"?>
(2)<!DOCTYPE html PUBLIC 
(3)	"-//W3C//DTD XHTML 1.0 Transitional//EN"     
(4)	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
(5)<html xmlns="http://www.w3.org/1999/xhtml">
(6)	<head>
(7)		<meta name="generator" content="HTML Tidy, see www.w3.org" />       
(8)		<title></title>    
(9)	</head>    
(10)	<body>       
(11)		<table rules="none">          
(12)			<tr>             
(13)				<td>x1</td>          
(14)			</tr>          
(15)			<tr>             
(16)				<td>x2</td>          
(17)			</tr>          
(18)			<tr>             
(19)				<td>x3</td>          
(20)			</tr>       
(21)		</table>       
(22)		<blink>blinkender Text (... im Netscape Navigator)</blink>       
(23)		<hr color="86db7f" />       
(24)		<marquee>beweglicher Text (... im MS Internet Explorer)</marquee>    
(25)	</body> 
(26)</html> 


Modulares XHTML

XHTML v1.1 dekomponiert das ehemals durch genau eine DTD dargestellte HTML-Vokabular in einzelne problemspezifische Module. Zusätzlich wird die Sprache um die Ruby-Anmerkungen erweitert. Hierbei handelt es sich um einen simplen Annotationsmechanismus für beliebige Anmerkungen im Text, wie er im südasiatischen Sprachraum breite Verwendung findet.

Breite Aufmerksamkeit dürften die in XHTML v1.1 verwirklichten Modularisierungsaktivitäten wecken. Sie haben es sich sich zum Ziel gesetzt, die Sprache in verschiedene eigenständige Module aufzuteilen, um so die Wiederverwendung einzelner Teilbereiche (wie z.B. Tabellen, Graphiken, Listen) in anderen XML-Sprachen zu ermöglichen. Gleichzeitig können ausgewählte Module für bestimmte Endgeräte umgesetzt werden, beispielsweise für ressourcenbeschränkte mobile Endgeräte.
Im Detail definiert der Standard 22 Einzelmodule mit ihren spezifischen Aufgaben. Das Zentrum der Dekomposition bilden die vier Kernmodule Struktur, Text, Hypertext und Listen. Sie müssen zwingend durch eine Implementierung umgesetzt werden, um als konform zu XHTML v1.1 anerkannt zu werden.
Nachfolgend sind die Module und ihre Aufgabe sowie typische Elemente daraus zusammengefaßt:

Das Schema-Fragment zeigt die Nutzung beliebiger Elemente aus dem XHTML-Namensraum im QualifikationsprofilType.

Beispiel 6: Nutzung von XHTML in anderen XML-Sprachen
Beispiel 42: Nutzung von XHTML in anderen XML-Sprachen
(1)...
(2)	<xsd:complexType 
(3)		name="QualifikationsprofilType" 
(4)		mixed="true">
(5)		<xsd:choice 
(6)			minOccurs="0" 
(7)			maxOccurs="unbounded">       
(8)			<xsd:element ref="Qualifikation"/>       
(9)			<xsd:element ref="Leistungsstufe"/>       
(10)			<xsd:any 
(11)				namespace="http://www.w3.org/1999/xhtml" 
(12)				minOccurs="0" 
(13)				maxOccurs="unbounded"/>
(14)		</xsd:choice> 
(15)	</xsd:complexType>
(16)... 
(17)	<xsd:element 
(18)		name="Qualifikationsprofil" 
(19)		type="QualifikationsprofilType" 
(20)		minOccurs="0"/> 
(21)... 


Eine gültige Dokumentinstanz kann innerhalb des Elements Qualifikationsprofil jedes Element aus dem XHTML-Namensraum beinhalten:

Beispiel 7: Nutzung des XHTML-Namensraumes in einem eigenen Dokument
Beispiel 43: Nutzung des XHTML-Namensraumes in einem eigenen Dokument
(1)<?xml version="1.0" encoding="ISO-8859-1"?>
(2)<ProjektVerwaltung
(3)	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
(4)	xmlns:xhtml="http://www.w3.org/1999/xhtml"
(5)	xsi:noNamespaceSchemaLocation="http://www.jeckle.de/vorlesung/xml/examples/projektverwaltung.xsd">
(6)	<Person PersID="Pers01" mitarbeitInProjekt="Prj01">
(7)		<Vorname>Hans</Vorname>
(8)		<Nachname>Hinterhuber</Nachname>
(9)	</Person>
(10)	<Person PersID="Pers02" mitarbeitInProjekt="Prj02">
(11)		<Vorname>Franz</Vorname>
(12)		<Vorname>Xaver</Vorname>
(13)		<Nachname>Obermüller</Nachname>
(14)		<Qualifikationsprofil>
(15)			<xhtml:u>IT-Kompetenz</xhtml:u>
(16)			<xhtml:em>verschiedene</xhtml:em> Betriebssysteme und
(17)		   <Leistungsstufe>professionelle</Leistungsstufe>
(18)			<xhtml:em>
(19)				<Qualifikation>Programmierung</Qualifikation>
(20)			</xhtml:em>
(21)		   verschiedener Programmiersprachen
(22)		   <xhtml:em>
(23)				<xhtml:u>
(24)					<Qualifikation>Entwickler</Qualifikation>
(25)				</xhtml:u>
(26)			</xhtml:em> von 1988-1990
(27)		   <xhtml:u>
(28)				<Qualifikation>Projektleiterfunktion</Qualifikation>
(29)			</xhtml:u>
(30)		   von <xhtml:b>1990-93</xhtml:b> im X42-Projekt in Abteilung AB&amp;C
(31)		</Qualifikationsprofil>
(32)	</Person>
(33)	<Person PersID="Pers03" mitarbeitInProjekt="Prj02">
(34)		<Vorname>Fritz</Vorname>
(35)		<Nachname>Meier</Nachname>
(36)	</Person>
(37)	<Projekt ID="Prj01" Projektleiter="Pers01" Mitarbeiter="Pers01"/>
(38)	<Projekt ID="Prj02" Projektleiter="Pers02" Mitarbeiter="Pers03"/>
(39)</ProjektVerwaltung>
Download des Beispiels


XHTML und XML Schema

Parallel zur Modularisierung und den laufenden Erweiterungsaktivitäten zu XHTML wurde inzwischen auch an der Neufassung der Strukturbeschreibung gearbeitet. Da der Sprachumfang der SGML-basierten Sprache HTML mit der Reformulierung in XML (XHTML v1.0) nicht verändert wurde (auch XHTML v1.1 läßt diesen unangetastet) bestand auch keinerlei Notwendigkeit zur Überarbeitung der DTD-basierten Vokabularbeschreibung.
Mit dem abzusehenden Übergang zur nächsten Version des XHTML-Vokabulars, welche erstmals seit 1999 neue Elemente in die Sprache einführen wird, vollzieht sich auch die Umstellung auf XML Schema.
Bereits für XHTML v1.0 liegt Formulierung als XML Schema in einer nicht normativen W3C Note vor.

Ausblick auf XHTML v2.0

XHTML markiert die erste „echte“ Weiterentwicklung der XHTML-Sprachfamilie seit ihrer Löslösung von SGML und der daran anschließenden Fundierung auf XML.
Das gegenwärtig erst im Status eines Working Draft zugängliche Vokabular definiert einige neue Elemente und entfernt einige bekannte Konstrukte. Daher stellt es keine abwärtskompatible Weiterentwicklung der existierenden XHTML-Sprachfamilie dar, sondern entwirft vielmehr eine neue Hypertextsprache.
Nachfolgend werten einige Erweiterungen und Modifikationen gegenüber dem vertrauten XHTML an Beispielen diskutiert.

XHTML v2 wird keine explizite Angabe des Zeilenumbruchs durch den Anwender mehr unterstützen, sondern dies vollständig der Darstellungskomponente überlassen. Konkret wird das br-Element als veraltet gekennzeichnet und stattdessen zukünftig durch das neu eingeführte Element line ersetzt werden welches sich in ähnlicher Weise nutzen läßt.
Beispiel 44 zeigt ein XHTML-Fragment welches korrekt im Sinne der Festlegungen der ersten XHTML-Generation formuliert ist. Beispiel 45 stellt diesem die XHTML v2 konforme Darstellung gegenüber.

Beispiel 8: Ein gültiges XHTML v1.x-Dokumentfragment
Beispiel 44: Ein gültiges XHTML v1.x-Dokumentfragment
(1)<p>
(2)Habe nun, ach! Philosophie,<br/>
(3)Juristerei und Medizin,<br/>
(4)Und leider auch Theologie!<br/>
(5)</p>
Download des Beispiels


Beispiel 9: ... XHTML v2-konforme Formulierung
Beispiel 45: ... XHTML v2-konforme Formulierung
(1)<p>
(2)<line>Habe nun, ach! Philosophie,</line>
(3)<line>Juristerei und Medizin,</line>
(4)<line>Und leider auch Theologie!</line>
(5)</p>
Download des Beispiels


Die Beispiele 46 und 47 illustrieren die wohl augenscheinlichste Neuerung des XHTML v2 Sprachvorschlages. Das bisher zur Referenzierung von Bilddaten vorhergesehene Element img wird zugunsten des bereits existierenden Elements object für veraltet erklärt.
Hintergrund dieser Entscheidung ist der Versuch der Aufhebung der Asymmetrie in der Adressierung von referenzierten Bilddaten und sonstigen externen Daten eines nicht näher definierten Formats wie beispielsweise Applets.
Innerhalb des object-Elements übernimmt das Attribut data die Rolle der bisher durch src ausgedrückten Lokalisationsreferenz. Neu hinzu kommt die die Typisierung des referenzierten Objekts mittels MIME-Type, welcher im type-Attribut angegeben wird.
Zusätzlich zeigt das Beispiel 47 die Nutzung der standby-Angabe welche zur Aufnahme von Text dient der während des Objektladevorganges (d.h. der Dereferenzierung der durch data identifizierten Ressource) dem Anwender präsentiert werden kann.

Beispiel 10: Referenzierung einer externen Bilddatei in XHTML v2
Beispiel 46: Referenzierung einer externen Bilddatei in XHTML v2
(1)<img src="http://www.jeckle.de/images/logo.gif" alt="ein Logo" />
Download des Beispiels


Beispiel 11: ... und in XHTML v2
Beispiel 47: ... und in XHTML v2
(1)<object
(2)	data="http://www.jeckle.de/images/logo.gif"
(3)	type="image/gif"
(4)	standby="ein Logo" />
Download des Beispiels


Folgenschwerste Modifikation der bestehenden XHTML-Struktur dürfte die Entfernung der Überschriftenelemente h1 mit h6 sein. Diese Elemente welche bisher die hierarchische Position einer Überschrift absolut durch die Wahl des Elementtyps ausdrückten werden zukünftig durch zugunsten eines allgemeinen Hierarchieelements h nicht mehr unterstützt. Ein Grund dieser Entscheidung mag in der praktischen Verwendung der bisher angebotenen Überschriftselemente liegen. So wurden diese häufig zur Erreichung eines gewissen visuellen Verhaltens herangezogen, welches sich aus dem im Elementnamen ablesbaren Verhältnis der Elemente zueinander ablesen lies. So wird typischerweise ein Überschriftselement der Ebene zwei (h2) in einer kleineren oder schwächeren optischen Darstellung umgesetzt als eines der Ebene eins (h1).
In XHTML v2 ergibt sich die visuelle Präsentation ausschließlich aus dem Verhältnis der h-Elemente zu der sie umgebenden section. Daher entspricht die Formulierung des Beispiels 48 der aus 49 semantisch.

Beispiel 12: Überschriftsebenen in XHTML v1
Beispiel 48: Überschriftsebenen in XHTML v1
(1)<h2>Der Tragödie erster Teil</h2>
(2)<h3>Nacht</h3>
(3)<h3>Vor dem Tor</h3>
(4)...
(5)<h2>Der Tragödie zweiter Teil</h2>
(6)<h3>Anmutige Gegend</h3>
(7)<h3>Hochgewölbtes enges gotisches Zimmer</h3>
(8)...
Download des Beispiels


Beispiel 13: Äquivalente Formulierung in XHTML v2
Beispiel 49: Äquivalente Formulierung in XHTML v2
(1)<section>
(2)   <h>Der Tragödie erster Teil</h>
(3)   <section>
(4)      <h>Nacht</h>
(5)   </section>
(6)   <section>
(7)      <h>Vor dem Tor</h>
(8)   </section>
(9)</section>
(10)...
Download des Beispiels


Die unauffälligste und gleichermaßen wirkungsmächtigste Neuerung ergibt sich aus der Inklusion des href-Attributes in die Zusammenstellung der allgemeine verwendbaren Attribute der Common Attribute Collection.
Diese „Aufwertung“ des genannten Attributs eröffnet die Möglichkeit beliebige XHTML-Elemente als Quellen von Hyperlinkverknüpfungen heranzuziehen wie es 50 zeigt.

Beispiel 14: Erweiterte Hyperlinks in XHTML v2
Beispiel 50: Erweiterte Hyperlinks in XHTML v2
(1)<p href="http://spiegel.gutenberg.de/faust">
(2)   <line>Habe nun, ach! <span href="http://www.philosophie.de">Philosophie</span>,</line>
(3)   <line><acronym title="Juristerei" xml:lang="de-au" href="http://www.austria.at">Jus</acronym>
(4)   <abbr title="und" href="http://www...">u.</abbr> Medizin,</line>
(5)   <line href="http://www.was-hat-goethe-gegen-theologie.de">Und leider auch Theologie!</line>
(6)</p>
Download des Beispiels


Obwohl das Beispiel auf den ersten Blick einen interessanten Mächtigkeitsgewinn erkennbar werden läßt, birgt es jedoch verschiedene Problemstellungen.
So ist das Interaktionsverhalten von Hyperlinks jenseits des bekannten a vollständig undefiniert und ihre überlappende Definition (wie durch die Einbettung des Elements line in das bereits mit einem Hyperlink versehene Element p illustriert) wirft die Frage nach der Behandlung durch das Anzeigegerät auf.
Auch führt dieser neu einzuführende Mechanismus notwendigerweise mit der aus verschiedenen Browsern bekannten Darstellungsweise von Hyperlinks durch blau gefärbten und unterstrichenen Text. So müßte das Beispieldokument vollständig gefärbt und unterstrichen dargestellt werden, was sich zweifellos als der Lesbarkeit nicht zuträglich erweisen würde.
Überdies entwickelt XHTML durch die diskutierte Vorgehensweise einen allgemein verwendbaren Referenzierungsmechanismus neu, der bereits durch den Standard XLink verfügbar ist. Vielmehr noch ergeben sich auf der zulässigen Kombination beider Verfahren weitere Problemstellungen.
Vor dem Hintergrund dieser Kritikpunkte ist nicht damit zu rechnen, daß die bestehende Form der erweiterten Hyperlinks in den letztendlich verabschliedeten Standard eingang finden wird.

XML über HTTP

Ähnlich der Übertragung von klassischem HTML über HTTP zur Anzeige in Web-Browsern kann auch reines XML „direkt“ per HTTP transportiert werden. Naturgemäß ist hierfür jedoch, anders als für (X)HTML, keine visuelle Repräsentation durch das empfangende Endgerät festgelegt.
Einige Hersteller bieten für natives XML strukturierte baumartige Darstellungen an. Der bekannteste Vertreter dieser Klasse dürfte Microsofts Internet Explorer sein, der ab Version 5.0 auch XML-Eingangsdaten unterstützt. Seine Browseransicht für das Beispieldokument ist im nachfolgenden Bildschirmabzug wiedergegeben.
Über Zuordnung von Präsentationsinformation durch XML Stylesheets (siehe Kapitel 2.4) kann XML direkt an einen Web-Client gesendet werden. Zur Anzeige der Informationen wird im Browser ein Stylesheet herangezogen. Genau dieses Prinzip ist auch durch den Internet Explorer verwirklicht; dort wird auf jedem XML-Dokument, welches keine eigene Stylesheetquelle identifiziert, eine Vorgabetransformation durchgeführt, welche die abgebildete Baumstruktur erzeugt.
Andere Browser unterstützen dieses Verhalten nicht und präsentieren daher für XML-Dokumente ohne assoziiertes Stylesheet lediglich einen leeren Bildschirm.

Natives XML in der Darstellung des MS Internet Explorers
Natives XML in der Darstellung des Mozilla Browsers
Web-Referenzen 3: Weiterführende Links
Web-Referenzen 10: Weiterführende Links


back to top   2  XML-Standards und -Anwendungen der zweiten Generation ...

 

Das nachfolgende Kapitel beleuchtet aufbauend auf den Grundlagen des ersten Abschnittes einige der sog. XML Standards der zweiten Generation.
Sie bilden zugleich als erste Anwendungen der eXtensible Markup Language auch Sprachen im engeren Sinne, da sie neben der Syntax auch Semantikdefinition, zumeist in Form eines Ausführungsmodells, umfassen.

Generationen der XML-Standards

Die Abbildung stellt die verschiedenen Generationen der XML-Standards in der Übersicht dar. Den Anfang -- augenzwinkernd als Web-Prähistorie bezeichnet -- bildet die bekannte Hypertextsprache HTML. Die erste Standardgeneration läßt sich an der Verabschiedung der XML-Recommendation im Februar 1998 festmachen. In der Folge wurden erste XML-Sprachen, wie XHTML, entwickelt. Wesentlich komplettiert wird diese erste Entwicklungsstufe durch die XML-Namensräume. Auf der Basis des Urstandards und dieser ersten Erweiterung, die selbst als XML-Sprache realisiert ist, entstanden die ersten weiter verbreiteten XML-Sprachen für produktive Zwecke. Beispielsweise die erweiterten Hyperlinks der Spezifikation XLink, aber auch die Stylesheetsprache XSL zur Erzeugung verschiedener Präsentationssichten auf Basis von XML-Dokumenten, sowie die Transformationssprache XSLT ! zur Umwandlung von XML-Dokumenten in verschiedene Ausgabeformate.
Mit der Integration der Namensräume in die XML-Spezifikation (XML 2nd edition) vollzieht sich bereits andeutungsweise der Übergang zur neuen konzeptionellen Basis der Metasprache XML. Am deutlichsten wird dieser Evolutionsschritt durch die Verabschiedung des XML-Schemastandards im Mai 2001 markiert. Er löst den bisherigen -- von SGML übernommenen -- Grammatikmechanismus der Document Type Definition ab, und legt die XML als selbstbeschreibende Metasprache an. Gemeinsam mit XML v1.0 2nd edition bildet diese W3C-Recommendation die neue technische Basis der weiteren Standardisierungsbemühungen. Die Graphik verwendet hierfür den teilweise anzutreffenden Begriff einer XML v2.0, der jedoch in dieser Form nicht durch das W3C geprägt wurde. Aufbauend auf diesem Fundament werden einige der bereits bestehenden XML-Co-Standards überarbeitet und auf die neuen Randbedingungen, wie XML-Schema, abgestimmt.

2.1   (Dokument-)Verknüpfungen: XML Links

Hyperlinking, als Möglichkeit der nichtlinearen wahlfreien Navigation in Dokumenten und zwischen beliebigen Ressourcen, ist in Zeiten des WWW allgegenwärtig. Zumeist werden die bekannten Sprungstellen im (X)HTML-Dokument farblich und zusätzlich durch Unterstreichung hervorgehoben dargestellt; ein simpler Mausklick verzweigt zur referenzierten Adresse oder aktiviert die hinterlegte Reaktion.
Bei genauerer Betrachtung läßt sich noch ein zweiter Verweismechanismus in (X)HTML identifizieren: die Referenzierung Dokument-externer Graphikdateien. Die (X)HTML-Datei enthält lediglich einen Verweis auf die URI der Graphik; die automatische Auflösung der Referenz, das Laden der Datei und die Integration in das (X)HTML-Dokument an der Stelle des img-Elements übernimmt der HTML-Agent (Browser oder sonstiges Anzeigegerät) ohne Interaktion durch den Anwender. Dieser Vorgang der automatisierten einbettenden Referenzierung wird Transklusion genannt. Der Begriff geht auf Ted Nelson und sein Xanadu-Projekt zurück. Der Terminus verbindet die beiden Worte Transfer und Inklusion um auf die beliebige physische Lokation der referenzierten Ressource und ihre transparente Einbindung in das Zieldokument gleichermaßen hinzuweisen.
Konzeptionell bilden beide Verweisarten unidirektional navigierbare (d.h. vom Quelldokument zur referenzierten Zielressource traversierbare) Verknüpfungen, die syntaktisch in das Quelldokument eingebunden werden. Das Verweisziel bleibt von der Bildung des Links unberührt.
So flexibel und naheliegend dieser Ansatz auf den ersten Blick scheinen mag, dennoch birgt er im praktischen Einsatz durchaus ernstzunehmende Unwägbarkeiten. Die bekannteste Ausprägung dürfte der HTTP-Fehler 404 -- Not Found -- sein. Er signalisiert der anfragenden Instanz, daß die angeforderte URI nicht gefunden werden konnte (spezifikationsgemäß möglich, wenn auch seltener genutzt, ist für diesen Fall auch Fehlercode 403 -- Forbidden -- zugelassen (siehe HTTP v1.0 Spezifikation IETF RFC 1945)).
Die Fehlersituation entsteht zumeist durch Referenzierung einer zwischenzeitlich gelöschten oder umgezogenen URI. Zwar läßt die HTTP v1.1 Spezifikation mit dem Fehlercode 410 -- Gone -- Rückschlüsse auf die frühere Gültigkeit der URI zu, jedoch schlägt auch in diesem Falle der Referenzierungsversuch fehl (siehe HTTP v1.1 Spezifikation IETF RFC 2068).
Die Grundidee des in (X)HTML verwirklichten Linkingmechanismus läßt keine Möglichkeit zur Vermeidung diese Situation zu, da die referenzierte (d.h. unabhängige) Instanz keinerlei Information über den gesetzten Verweis innerhalb des abhängigen Dokuments erhält.

Gemeinsames Kennzeichen der beiden Verweisarten ist die direkte explizite Einbettung der Links in das Quelldokument. Hierdurch werden Pflege des Dokumentinhaltes und der Verweise an derselben organisatorischen Stelle konzentriert, Änderungen an den gesetzten Verweisen ziehen in jedem Falle Änderungen am verweisenden Dokument nach sich.
Als Folge können Dokumente nicht durch Externe auf dem Wege der Annotation durch Verweise ergänzt werden. Technisch erfordert dieses Vorgehen neben der verknüpften Quell- und Zielressource eine dritte Instanz zur unabhängigen Speicherung der Verweise.
Eine konkrete Umsetzung der freien Annotation beliebiger WWW-Seiten durch Dritte bot der, mittlerweile eingestellte, Dienst Third Voice.

Die klassischen HTML-Hyperlinks sind als Bestandteil der XML-Sprache XHTML durch Strukturen ihrer Grammatikdefinition in Form von Elementen und Attributen realisiert. Sie siedeln sich damit im Anwendungsbereich der XML an, und stehen daher nicht sprachunabhängig für alle XML-Sprachen zur Verfügung.
Durch die XML-Grundauffassung einer Welt vernetzter unabhängiger Dokumente ergibt sich die natürliche Notwendigkeit zur Schaffung eines Verweismechanismus, der für beliebige XML-Sprachen gleichermaßen universell eingesetzt werden kann. Dieser Anforderung soll die XML Linking Language (XLink) genügen.

Der Sprachstandard XLink behebt dieses Manko und schlägt für beliebige XML-Sprachen ein Vokabular mit zugehöriger Semantikdefinition zur Realisierung beliebiger Verweisstrukturen vor. Konzeptionell bildet XLink eine Obermenge des klassischen href-Elements.

Definition 12: XML Linking Language
Definition 12: XML Linking Language

Die XML Linking Language (XLink) definiert ein XML-basiertes Vokabular zur Darstellung allgemeiner Verweise in einem XML-Dokument.
Die Verwendung von XLink ist nicht an ein konkretes XML-Vokabular gebunden.
XLink-konforme Verweise können sowohl in einem Dokument ausgedrückt sein, als auch in einer externen Datenstruktur -- der sog. Linkbase -- verwaltet werden.



Erste Umsetzungen der Standardvorschlages existieren, neben einigen Spezialwerkzeugen, in den Web-Browsern Netscape (ab Version sechs) und dem Open-Source Projekt Mozilla.

Die XML Linking Spezifikation definiert in einem eigenen Namensraum eine Reihe von Attributen mit zulässigen Wertbelegungen, die für die Verwendung in eigenen XML-Sprachen zur Verfügung stehen.
Durch die Beschränkung auf Attributdefinitionen wird dem Anwender ein zusätzlicher Freiheitsgrad gegenüber der bisherigen (X)HTML-Verweismimik eröffnet. Während in Hypertextdokumenten Links ausschließlich durch Spezifikation des Attributs href im Ankerelement a definiert werden konnten, können die XLink-Attribute in beliebigen Elementen verwendet werden.

Im Einzelnen definiert die XLink-Spezifikation folgende Attribute und Wertbelegungen:

Tabelle  17: XLink-Attribute
Tabelle 17: XLink-Attribute
Attribut
zulässige Belegung
Semantik
type
simple, extended, locator, arc, resource, title
Die verschiedenen durch die Spezifikation vorgegebenen XLink-Typen
href
Jede gültige URI gemäß IETF RFC 2396
Verweis auf die referenzierte Ressource
role
Jede gültige URI gemäß IETF RFC 2396
Verweis auf eine Ressource, welche eine nähere Beschreibung der referenzierten Ressource enthält; verwendet für simple, extended, locator oder resource typisierte Links
arcrole
Jede gültige URI gemäß IETF RFC 2396
Verweis auf eine Ressource, verwendet für simple oder arc typisierte Links
Freier Text
Beschreibt die Bedeutung des Verweises in lesbarem Format
show
new, replace, embed, other, none
Verhalten des Verweises bei seiner Aktivierung.
new öffnet die referenzierte Resource in einem neuen Fenster (entspricht damit der (X)HTML-Definition <a href="http://www.jeckle.de" target="_blank">...</a>),
replace ersetzt den aktuellen Fensterinhalt (entspricht damit der (X)HTML-Definition <a href="http://www.jeckle.de" target="_self">..</a>),
embed ersetzt den Verweis durch den Inhalt der referenzierten Resource (entspricht damit der (X)HTML-Definition <img src="http://www.w3.org/Icons/w3c_home.gif" />),
other erlaubt die Definition beliebiger eigener Aktionen durch Markup.
none definiert, daß durch den Client keine Standardaktion bei Linkaktivierung auszuführen ist.
Die hier gegebenen Interpretationen der Aktionen sind stark an denen eines Web-Browsers orientiert, und können daher für andere Endgeräte beliebig variieren bzw. unter Umständen garnicht angeboten werden.
actuate
onLoad, onRequest, other, none
onLoad bewirkt die automatische Aktivierung des XLinks, das Verhalten entspricht damit dem des (X)HTML-Elements img.
Wird onRequest spezifiziert, so kann der Verweis durch den Anwender interaktiv wahlfrei aktiviert werden. Das Verhalten entspricht hierbei den bekannten Hypertextlinks.
other definiert durch weiteres Markup spezifiziertes freies Verhalten, welches durch das Endgerät umgesetzt wird.
Bei none kann durch den interpretierenden Client eine im XML-Sinne proprietäre, d.h. nicht durch Markup spezifizierte, Verhaltensdefinition angegeben werden.
label
Jeder zulässige NCName.
Definiert textuelle Identifikation des XLinks
from
Jeder zulässige NCName, der angegebene Wert muß dem eines existierenden label-Attributs entsprechen.
Verweisquelle eines erweiterten XLinks
to
Jeder zulässige NCName, der angegebene Wert muß dem eines existierenden label-Attributs entsprechen.
Verweisziel eines erweiterten XLinks


Je nach ihrer Belegung definierten die XLink-Attribute drei verschiedene Linktypen, die relativ zu einem Bezugsdokument benannt werden.
Verweist das href-Attribtut eines XLinks lediglich auf eine Ressource innerhalb des Bezugsdokuments, dann handelt es sich um einen Local Link. Wird auf eine anderes Dokument verwiesen, so spricht man von einem Outbound Link. Umgekehrt, d.h. im Falle eins externen Verweises auf das Bezugsdokument, so wird dieser als Inbound Link bezeichnet. Inbound und Outbound Links entsprechen sich daher, jeweils mit geändertem Bezugspunkt.
Abbildung 27 stellt die Typen in der Übersicht zusammen.

Die XLink-Typen in der Übersicht

Als besondere Form existiert mit dem Linktyp des External Links ein Verweistyp, der sich nicht in obiges Schema fügt. In seinem Falle wird der gesamte XLink in einer externen Ressource gehalten, die selbst nicht notwendigerweise in XML-Dokument sein muß.
Dieses externe Linkverzeichnis wird Link Base genannt, es ist typischerweise durch eine Datenbank umgesetzt.

Beispiel 51 zeigt die Definitionen der einfachsten Form eines XLinks, den sog. simple Link. Benannt ist diese Darstellung nach dem Wert des type-Attributs.
Im Beispiel wird durch das Element myElementA ein Verweis definiert, dessen Verhalten den (X)HTML-Hyperlinks entspricht. Zunächst ist zur Identifikation der XLink-Attribute der durch die Spezifikation vorgegebene Namensraum http://www.w3.org/1999/xlink festzulegen; daher wird dieser an das Präfix xlink gebunden.
Die Definition als Vorgabenamensraum ist für diesen Anwendungsfall nicht möglich, da sich Namensräume vorgabegemäß nur auf Elemente auswirken.
Das Verweisziel wird in Form des href-Attributs (im XLink-Namensraum) angegeben.

Beispiel 1: Ein simple XLink
Beispiel 51: Ein simple XLink
(1)<myElementA
(2)	xmlns:xlink="http://www.w3.org/1999/xlink"
(3)	xlink:type="simple"
(4)	xlink:href="http://www.jeckle.de">...</myElementA>


Der transklutorischen (d.h. die referenzierte Ressource einbettenden und automatisch aktivierten) Graphik-Referenz des img-Elements aus (X)HTML entspricht folgendes Konstrukt:

Beispiel 2: Ein transklutorischer Link
Beispiel 52: Ein transklutorischer Link
(1)<myElementB 
(2)	xmlns:xlink="http://www.w3.org/1999/xlink"
(3)	xlink:type="simple"
(4)	xlink:href="http://www.w3.org/Icons/w3c_home.gif"
(5)	xlink:actuate="onLoad"
(6)	xlink:show="embed">...</myElementB> 


Durch die zusätzlichen angebbaren Attribute läßt sich die Semantik eines Links spezifizieren. Dies stellt eine erste Erweiterung der Mächtigkeit gegenüber den bisher im Vergleich zu (X)HTML diskutierten Verweisen dar.
So erlaubt das title-Attribut die genauere Charakterisierung eines Links durch beliebigen anwenderdefinierten Freitext.
Am Beispiel der Projektverwaltung: Das nachfolgende Codefragment realisiert die Beziehung zwischen Projekt und seinen Mitarbeitern, die in einer anderen Datei abgespeichert sind, durch einen XLink.

Beispiel 3: Nutzung des title-Attributs
Beispiel 53: Nutzung des title-Attributs
(1)<Projektverwaltung 
(2)	xmlns:xlink="http://www.w3.org/1999/xlink">
(3)	...    
(4)	<Projekt
(5)		xlink:type="simple"    
(6)		xlink:href="../xyz.xml"    
(7)		xlink:title="Liste der Projektmitarbeiter">...</Projekt>
(8)	 ... 
(9)</Projektverwaltung> 


Definition 13: Simpler XLink
Definition 13: Simpler XLink
Ein simpler XLink ist eine unidirektionale Verbindung zwischen zwei Ressourcen, wobei eine Ressource als Quelle und die andere als Ziel des Links interpretiert wird.


Während die simplen XLinks größtenteils in Analogie oder behutsamer Erweiterung zum entsprechenden (X)HTML-Konzept aufgebaut sind, führen die extended links bisher nicht realisierbare Möglichkeiten ein.
Wiederum am Beispiel der Projektverwaltung: Zwar läßt das vorhergehende Codefragment die Referenzierung der Projektmitarbeiter zu, jedoch kann innerhalb des Projekt-Elements kein weiterer XLink als Verweis auf die Projektleiter gesetzt werden, da sonst mehrfach dasselbe Attribut auftreten würde.
Das zugrundeliegende Problem, nämlich der Wunsch durch einen Link mehrere Ressourcen gebündelt referenzieren zu können, tritt in praktischen Anwendungen häufig auf. Beispielsweise beim Verweis auf mehrere Versionen eines Dokuments, alternativen Downloadservern oder Bildern verschiedener Auflösung.
Zu Realisierung erlaubt XLink die Bündelung von verschiedenen Verweisen zu einem einzigen erweiterten XLink. Nachfolgend ein Codeausschnitt, der dies für die Projektverwaltung zeigt.

Definition 14: Extended XLink
Definition 14: Extended XLink
Ein erweiterter XLink kann gleichzeitig auf mehr als eine Ressource verweisen.


Beispiel 4: Ein Verweis auf mehrere Ressourcen
Beispiel 54: Ein Verweis auf mehrere Ressourcen
(1)<Projekt 
(2)	xmlns:xlink="http://www.w3.org/1999/xlink"
(3)	xlink:type="extended">    
(4)	<Person 
(5)		xlink:type="locator"
(6)		xlink:href="urn:names:meier"
(7)		xlink:label="ID001"
(8)		xlink:title="Projektleiter"
(9)		xlink:role="http://www.example.com/contracts/projectLeader"/>
(10)	<Person 
(11)		xlink:type="locator"
(12)		xlink:href="urn:names:huber"
(13)		xlink:label="ID002"
(14)		xlink:title="Mitarbeiter"
(15)		xlink:role="http://www.example.com/contracts/employee"/>
(16)	<Person 
(17)		xlink:type="locator"
(18)		xlink:href="urn:names:müller"
(19)		xlink:label="ID003"
(20)		xlink:title="Mitarbeiter"
(21)		xlink:role="http://www.example.com/contracts/employee"/>
(22)	</Projekt>


Das Beispiel definiert einen dreigliedrigen extended link. Zur Realisierung ist zunächst das type-Attribut des die Einzellinks umschließenden Elements auf extended zu setzen. Im Rumpf dieses Elements folgen die als locator typisierten Verweise auf die verschiedenen Ressourcen. Die von den simple-Links bekannten XLink-Attribute href zur URI-basierten Referenzierung der Ressource, title zur natürlichsprachlichen Beschreibung des Verweises, sowie role zur Referenzierung einer beschreibenden Resource, können mit gleicher Semantik weiterverwendet werden. Zusätzlich nutzt das Beispiel die Möglichkeit der eindeutigen Identifikation der Verweisteile innerhalb des extended Links durch das label-Attribut.

Ein dreigliedriger erweiterter XLink

Generell trifft das Konstrukt des erweiterten Links keine Vorgabe über mögliche Navigationsrichtungen zwischen allen im Rumpf des Linkelements aufgeführten Ressourcen.
Die Graphik stellt die referenzierten externen Ressourcen Meier, Huber und Müller als Rechteckte die durch den als Dreieck dargestellten erweiterten Link verbunden sind dar.
Es kann jedoch der Wunsch bestehen Beziehungen zwischen den durch einen erweiterten XLink verbundenen Ressourcen zu definieren. Hierfür gibt der Standard das arc-Attribut vor.

Zusätzlich zu diesem Attribut kann die Traversierungsrichtung des Links durch die Attribute from und to festgelegt werden. Die Graphik stellt diese Beziehungen als unterbrochene gerichtete Kanten dar.
Implizit kann daher die Existenz dieses Attribut-Tripels für simple XLinks angenommen werden.
Für das vorhergehende Beispiel ist die Navigationsdefinition dergestalt gewählt, daß eine Beziehung zwischen der Ressource Müller und Huber besteht. Diese Beziehung wird durch das Element befreundet_mit definiert. Zusätzlich etabliert das Element Bruder_von durch das arc-Attribut eine Beziehung zwischen Müller und Meier.

Beispiel 5: Eingeschränkte Navigation innerhalb eines extended XLinks
Beispiel 55: Eingeschränkte Navigation innerhalb eines extended XLinks
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<Projekt 
(3)   xmlns="http://www.jeckle.de/vorlesung/xml"
(4)	xmlns:xlink="http://www.w3.org/1999/xlink" 
(5)	xlink:type="extended">    
(6)	<Person 
(7)		xlink:type="locator"    
(8)		xlink:href="urn:names:meier"    
(9)		xlink:label="ID001"
(10)		xlink:title="Projektleiter"    
(11)		xlink:role="http://www.example.com/contracts/projectLeader" />    
(12)	<Person 
(13)		xlink:type="locator"    
(14)		xlink:href="urn:names:huber"    
(15)		xlink:label="ID002"
(16)		xlink:title="Mitarbeiter"    
(17)		xlink:role="http://www.example.com/contracts/employee" />    
(18)	<Person 
(19)		xlink:type="locator"    
(20)		xlink:href="urn:names:müller"    
(21)		xlink:label="ID003"
(22)		xlink:title="Mitarbeiter"    
(23)		xlink:role="http://www.example.com/contracts/employee" />    
(24)	<befreundet_mit 
(25)		xlink:type="arc"
(26)		xlink:from="ID003"
(27)		xlink:to="ID002"/>    
(28)	<Bruder_von 
(29)		xlink:type="arc"
(30)		xlink:from="ID003"
(31)		xlink:to="ID001"/> 
(32)</Projekt>


Das Beispiel verwendet zur Referenzierung der einzelnen Ressourcen das XLink-Attribut label.
Abschließend bleibt anzumerken, daß die arc-Typisierung lediglich die positive Definition explizit erlaubter Traversierungspfade erlaubt. Eine Einschränkung der Vorgabepfade ist nicht möglich.

Neben den bisher diskutierten Verweisen, bei denen es sich ausschließlich um Outbound Links handelte, läßt XLink auch die Auslagerung der Referenzierungen in eine sog. Link Database (kurz: Linkbase) zu. Ein solcher Datenspeicher enthält eine Menge von Zwei-Tupeln , welche Quelle und Ziel eines Verweises wiedergeben. Eine geeignete Applikation muß zur Realisierung der Verzeigerung immer eine Anfrage an diese Datenbank absetzen, und das Quell-Dokument unter Umständen geeignet aufbereiten, um dem Anwender die Möglichkeit zur Interaktion zu geben.
Das Schema der Abbildung stellt die beiden Verweismechanismen in der Zusammenschau dar. Im oberen Bereich ist ein inline link angedeutet, der im Quelldokument die zur Lokalisierung und Anzeige der referenzierten Ressource notwendigen Daten enthält. Im unteren Bereich ist das Konzept einer externen Linkdatenbank, die vor Anzeige des durch sie annotierten Quelldokuments zu konsultieren ist.

Interne und externe Links

Für das Anwendungsszenario der externen Linkdatenbank stellt sich die Frage nach dem Aussehen der in der Datenbank abgespeicherten Zwei-Tupel. Während die Notation des Verweisziels durch die URI (IETF RFC 2396) vorgegeben ist, eröffnet sich die Frage nach der Lokalisierung des Verweises selbst innerhalb des Quelldokuments.
Unter Rückgriff auf (X)HTML ließen sich zwar durch die explizite Definition von Textankern (a-Element mit name-Attribut) beliebige Stellen als Aufsetzpunkt von extern verwalteten Verweisen definieren, jedoch würde dies erhebliche Modifikationen am Quelldokument nach sich ziehen, die bei Dokumentänderungen ihrerseits wiederum Wartungsarbeiten erfordern würden.
Idealerweise sollte das Quelldokument durch die Definition extern abgelegter Verweise nicht berührt werden. Im Falle eines freien Annotationsdienstes, der durch Dritte genutzt werden kann, stellt dies sogar eine Grundforderung dar.
Dieser Anwendungsfall bildet -- neben anderen -- ein Anwendungsszenario, welches eine Möglichkeit zur flexiblen Lokalisierung von Dokumentteilen erfordert. Hierfür wurde durch das W3C die im nachfolgenden Abschnitt vorgestellte XML Path Language verabschiedet.

XML Base

Um die Möglichkeiten der klassischen Hypertextverknüpfungen aus HTML auch für XML vollständig nachzubilden fehlt XLink in der Grundform die Unterstützung relativer Verweise.
Diese aus (X)HTML bekannte Kurzschreibweise dient zur Adressierung eines Teils einer durch URI identifizierten Ressource. In Hypertextdokumenten werden solche Verweise häufig zur direkten Navigation zu Teilkapitel oder Zwischenüberschriften verwendet.

Zur Realisierung müssen die Sprungziele im Dokument durch den Autor festgelegt werden. (X)HTML bietet hierfür das id-Attribut an. In Verbindung mit dem Anker-Element erlaubt es die freie Definition von Sprungzielen innerhalb beliebiger XHTML-Dokumente.
Syntaktisch kann dabei der durch das #-Symbol vom Ankernamen separierte Identifikator einer URI nachgestellt werden um auf ein Sprungziel innerhalb der durch die URI bezeichneten Ressource zu verweisen. Abkürzend kann -- durch Weglassung der URI -- auf Anker des aktuellen Dokuments verwiesen werden.

Das XHTML-Dokument des Beispiels 56 zeigt die beiden Nutzungsvarianten relativer Verweise.
Die mit Zueignung, Vorspiel und Prolog benannten Anker adressieren die im Beispieldokument plazierten Ressourcen gleichen Namens (a-Elemente mit gesetztem id-Attribut).
Die übrigen Verweise (etwa Teil1.html#Nacht) nehmen Bezug auf benannte Ressourcen anderer Quellen (etwa innerhalb des Dokuments Teil1.html). Diese Quellen müssen zur Gewährleistung der Auflösbarkeit die notwendigen Anker-Elemente definieren.

Beispiel 6: Hypertext-Dokument mit HTML-konformen Verweisen
Beispiel 56: Hypertext-Dokument mit HTML-konformen Verweisen
(1)<?xml version="1.0" encoding="ISO-8859-1"?>
(2)<html xmlns="http://www.w3.org/1999/xhtml">
(3)   <head>
(4)      <title>J. W. von Goethe: FAUST</title>
(5)   </head>
(6)
(7)   <body>
(8)      <h1>Inhaltsverzeichnis</h1>
(9)      <ul>
(10)         <li><a href="#Zueignung">Zueignung</a></li>
(11)         <li><a href="#Vorspiel">Vorspiel auf dem Theater</a></li>
(12)         <li><a href="#Prolog">Prolog im Himmel</a></li>
(13)      </ul>
(14)
(15)      <ol>
(16)         <li>
(17)            <h2>Der Tragödie erster Teil</h2>
(18)            <ul>
(19)               <li><a href="http://www.example.com/Teil1/Akt1.html#Nacht">Nacht</a></li>
(20)               <li><a href="http://www.example.com/Teil1/Akt1.html#Tor">Vor dem Tor</a></li>
(21)               <li><a href="http://www.example.com/Teil1/Akt1.html#Studierzimmer">Studierzimmer</a></li>
(22)               <li><p>...</p></li>
(23)            </ul>
(24)         </li>
(25)
(26)         <li>
(27)            <h2>Der Tragödie zweiter Teil</h2>
(28)            <ul>
(29)               <li><a href="http://www.example.com/Teil2/Akt1.html#AnmGegend">Anmutige Gegend</a></li>
(30)               <li><a href="http://www.example.com/Teil2/Akt1.html#gotZimmer">Hochgewölbtes enges gotisches Zimmer</a></li>
(31)               <li><a href="http://www.example.com/Teil2/Akt1.html#Palast">Vor dem Palaste des Menelas zu Sparta</a></li>
(32)               <li>...</li>
(33)            </ul>
(34)         </li>
(35)      </ol>
(36)
(37)      <hr />
(38)
(39)      <h1><a id="Zueignung">Zueignung</a></h1>
(40)      <p>Ihr naht euch wieder, ...</p>
(41)
(42)      <h1><a id="Vorspiel">Vorspiel auf dem Theater</a></h1>
(43)      <p>Direktor. Ihr beiden, die ihr mir so oft, ...</p>
(44)
(45)      <h1><a id="Prolog">Prolog im Himmel</a></h1>
(46)      <p>Raphael. Die Sonne t?nach alter Weise ...</p>
(47)   </body>
(48)</html>
Download des Beispiels


Während innerhalb des (X)HTML-Dokuments relative Verweise durch die URI des umgebenden Dokumentes ergänzt werden können ist dies für XML-Dokumente im allgemeinen Falle nicht anzunehmen. Aus diesem Grunde definiert der W3C-Standard XML Base einen einfachen Mechanismus zur Nachbildung der in (X)HTML verwirklichten Mimik.

Zur Realisierung relativer Verweise definiert XML Base ein aus genau einem Attribut bestehendes XML-Vokabular. Dieses Attribut -- xml:base -- dient zur Aufnahme des URI-Anteils. Alle referenzierenden Informationselemente, beispielsweise href, die innerhalb des mit diesem Attribut versehenen Element oder innerhalb seiner Kindelemente auftreten werden relativ zur im xml:base-Attribut angegebenen URI interpretiert. Intuitiv wird diese dynamisch vor dem Fragmentidentifikator plaziert und mit ihm zu einer neuen URI konkateniert.
Dieser Vorgang kann auch über mehrere Stufen des XML-Dokumentbaumes vollzogen werden. Hierzu werden die Inhalte aller xml:base-Attribute die sich in hierarchisch übergeordneten Elementen des referenzierenden Knotens befinden zusammengefügt.

Das Beispiel der Abbildung 57 formuliert den XHTML-Code des vorangegangenen Beispiels XML Base-konform um.
Daher wird zunächst der URI-Anteil der für alle Verweise gleichermaßen gilt auf einem hierarchisch höherstehenden gemeinsamen Element als Belegung des Attributs xml:base definiert. Im Beispiel wird daher die Basis-URI http://www.example.com/ im entsprechenden Attribut des Wurzelelements html plaziert.
Die Dokumentinternen Verweise (sie folgen auf den Text Inhaltsverzeichnis) ändern sich daher nicht. In diesem Falle expliziert xml:base lediglich die im XHTML durch seine physische Lokation implizit gegebene Information.
Für die Verweise des Dokumentes Akt1.html im Pfad Teil1 hingegen tritt eine Veränderung des durch href formulierten Verweises ein. Denn auch in diesem Falle kann der gemeinsame Anteil wieder in das XML-Basis-Attribut ausgelagert werden. In der Konsequenz ergibt sich die vollständige URI des Verweises Nacht wieder als http://www.example.com/Teil1/Akt1.html#Nacht, die durch Hierarchie-konforme Hintereinanderreichung der xml:base-Inhalte entsteht.
Für die Verweise in das Dokument Akt1.html im Pfad Teil2 gilt dasselbe. Auch hier wird die zu dereferenzierende URI durch Konkatenation der XML-Basis-Attribute gebildet.
Durch die Organisation dieses xml:base-Attributs auf derselben Hierarchieebene wie das zuvor diskutierte ergibt sich auch in diesem Anwendungsfalle die korrekte URI als http://www.example.com/Teil2/Akt1.html.

Beispiel 7: Hypertext-Dokument mit XML-Base-konformen Verweisen
Beispiel 57: Hypertext-Dokument mit XML-Base-konformen Verweisen
(1)<?xml version="1.0" encoding="ISO-8859-1"?>
(2)<html xmlns="http://www.w3.org/1999/xhtml"
(3)	   xmlns:xlink="http://www.w3.org/1999/xlink"
(4)	   xmlns:book="http://www.example.org/books"
(5)      xml:base="http://www.example.com/">
(6)   <head>
(7)      <title>J. W. von Goethe: FAUST</title>
(8)   </head>
(9)
(10)   <body>
(11)      <h1>Inhaltsverzeichnis</h1>
(12)      <ul>
(13)         <li><book:chapter xlink:type="simple" id="zueignung">Zueignung</book:chapter></li>
(14)         <li><book:chapter xlink:type="simple" id="vat">Vorspiel auf dem Theater</book:chapter></li>
(15)         <li><book:chapter xlink:type="simple" id="prolog">Prolog im Himmel</book:chapter></li>
(16)      </ul>
(17)
(18)      <ol>
(19)         <li>
(20)            <h2>Der Tragödie erster Teil</h2>
(21)            <ul xml:base="/Teil1/Akt1.html">
(22)               <li><book:chapter xlink:type="simple" id="nacht">Nacht</book:chapter></li>
(23)               <li><book:chapter xlink:type="simple" id="vdTor">Vor dem Tor</book:chapter></li>
(24)               <li><book:chapter xlink:type="simple" id="studZi">Studierzimmer</book:chapter></li>
(25)               <li>...</li>
(26)            </ul>
(27)         </li>
(28)
(29)         <li>
(30)            <h2>Der Tragödie zweiter Teil</h2>
(31)            <ul xml:base="/Teil2/Akt1.html">
(32)               <li><book:chapter xlink:type="simple" id="anmGegend">Anmutige Gegend</book:chapter></li>
(33)               <li><book:chapter xlink:type="simple" id="gotZi">Hochgewölbtes enges gotisches Zimmer</book:chapter></li>
(34)               <li><book:chapter xlink:type="simple" id="palast">Vor dem Palaste des Menelas zu Sparta</book:chapter></li>
(35)               <li>...</li>
(36)            </ul>
(37)         </li>
(38)      </ol>
(39)   </body>
(40)</html>
Download des Beispiels


Web-Referenzen 1: Weiterführende Links
Web-Referenzen 11: Weiterführende Links


2.2   Die Lokatorsprache XPath

Zur Extraktion beliebiger Teile eines wohl-geformten XML-Dokuments verabschiedete das W3C 1999 die Sprache XPath. Sie bildet eine pfadorientierte Lokatorsprache, die das Auffinden von Dokumentteilen (einzelnen Elementen, Attributen, etc.) durch Pfadausdrücke, die sich an der Struktur des XML-Dokuments orientieren, gestattet.
Die Grenze zwischen Lokatorsprache und „echter“ Anfragesprache wie SQL sind fließend. Zwei Unterscheidungsmerkmale sollen jedoch hervorgehoben werden: XPath wird im üblichen Anwendungsfall nicht interaktiv oder in eine Programmiersprache als Wirtssprache eingebettet verwendet, sondern wurde (zunächst) nur für die Nutzung in Kombination mit der Transformationssprache XSLT und den erweiterten Verweisen der Sprache XPointer konzipiert. Zum zweiten fehlt XPath die üblicherweise mit dem reinen Anfrageteil verwobene Manipulationssprache zur Änderung bereits bestehender Daten; XPath ist allein für den lesenden Zugriff auf XML-Dokumente ausgelegt.
Hinweis: XPath unterscheidet XML-üblich zwischen Groß- und Kleinschreibung. Daher sind Element- und Attributnamen unbedingt in der im Dokument gewählten Schreibweise anzugeben.

Lokalisierungspfade:
Lokalisierungspfade dienen der abstrakten Beschreibung einer Menge von Informationsknoten innerhalb eines Dokuments.
Die einfachste Form eines Lokalisierungspfades beschreibt der Wurzellokalisierungpfad (root location path), ausgedrückt durch „/“. Er liefert für jedes XML-Dokument den Wurzelknoten. Dieser ist nicht identisch mit dem Wurzelelement eines XML-Dokuments! Der (unbenannte) Wurzelknoten entspricht dem Document Information Item des Information Sets, während das erste benannte Element des Dokuments durch ein Element Information Item dargestellt wird.

Die Navigation zu den einzelnen Elementknoten, oder Knotenmengen, wird durch einen Pfadausdruck realisiert. Die explizite Variante erlaubt die Angabe aller zu traversierenden Knoten bis hin zu den zu extrahierenden. Hierzu werden die Knoten, von der Wurzel absteigend durch „/“-Symbole separiert, notiert. Wegen der Korrespondenz der voneinander abgetrennten Knotennamen und den Baumstufen, werden diese auch als Lokalisierungsschritte bezeichnet. Als weitere sprachliche Analoge spiegelt der XPath-Ausdruck, von links nach rechts gelesen, auch die Schritte -- ausgehend vom Wurzelelement des Dokuments -- zur Lokalisierung der gesuchten Knotenmenge wieder.
Das Beispiel zeigt eine solche Definition am Beispiel der Projektverwaltung.
Anmerkung: Das Resultat ist in XML-Notation dargestellt, obwohl genaugenommen eine Knotenmenge des Information Sets als Resultat zurückgeliefert wird. Die gewählte XML-Darstellung ist hierbei nur eine der möglichen Varianten zur Ergebnispräsentation.

Beispiel 1: XPath-Ausdruck zur Lokalisierung aller Vornamen
Beispiel 58: XPath-Ausdruck zur Lokalisierung aller Vornamen
XPath-Ausdruck: /ProjektVerwaltung/Person/Vorname
Ergebnis: <Vorname>Hans</Vorname>, <Vorname>Franz</Vorname>, <Vorname>Xaver</Vorname>, <Vorname>Fritz</Vorname>


Die Einzelknoten werden entsprechend ihrer Auftrittsreihenfolge im Quelldokument (sog. document order) zurückgegeben.

Die expliziten Pfadausdrücke lassen sich in beliebiger Länge fortsetzen, jedoch zeigen sie fundamentale Schwächen in Puncto Flexibilität. Wie im Beispiel der XHTML-Verwendung innerhalb eines eigenen XML-Dokuments gesehen, kann Information desselben Typs (d.h. umschlossen durch denselben Tag) verschiedene Elternknoten besitzen. So im Beispiel, dort ist die Qualifikation auf derselben Baumstufe sowohl unterhalb des Elternelements em als auch u anzutreffen.
Als Lösung erlaubt XPath die Nutzung von Platzhaltern statt der expliziten Elementnamen innerhalb eines Lokalisierungsschrittes. In der Folge entstehen freie Lokalisierungsschritte, die alle Kindknoten einer im direkt vorhergehenden Lokalisierungsschritt selektierten Knotenmenge adressieren.
Der nachfolgende XPath-Ausdruck zeigt dies am Beispiel des Qualifikationsprofils.

Beispiel 2: Platzhalter in Lokalisierungsschritten
Beispiel 59: Platzhalter in Lokalisierungsschritten
XPath-Ausdruck: /ProjektVerwaltung/Person/Qualifikationsprofil/*/Qualifikation
Ergebnis: <Qualifikation>Programmierung</Qualifikation> <Qualifikation>Projektleiterfunktion</Qualifikation>


Der Pfadausdruck liefert die beiden Kindelemente Qualifikation -- unabhängig von der Benennung des Elternknotens -- die direkt unterhalb des Knotens Qualifikationsprofil angeordnet sind.
Allerdings enthält die Ausgabe nicht alle Knoten des Typs Qualifikation. Der gegebene Pfadausdruck gestattet lediglich das Überspringen einer Hierarchieebene. Daher wird der hierarchisch tieferstehende Qualifikations-Knoten mit Inhalt Entwickler nicht lokalisiert. Die (zunächst naheliegende) Lösung den Pfadausdruck zu /ProjektVerwaltung/Person/Qualifikationsprofil/*/*/Qualifikation zu erweitern liefert nicht das gewünschte Resultat aller Qualifikations-Knoten, sondern ausschließlich den zuvor nicht lokalisierbaren, da der modifizierte Ausdruck nun zwingend zwei freie Lokalisierungsschritte vorsieht.
Zur Variierung der Tiefe der freien Schritte sieht XPath die Schreibweise „//“ vor. Sie erlaubt die Lokalisierung der Kindknoten auf einer beliebigen Hierarchiestufe.

Definition 15: Lokalisierungsschritt
Definition 15: Lokalisierungsschritt
Ein Lokalisierungsschritt setzt sich aus dem Namen der Achse gefolgt von zwei Doppelpunkten und einem Knotentest, optional ergänzt um ein auszuwertendes Prädikat, zusammen.
Wird keine Achse spezifiziert, so gilt vorgabegemäß die Achse child.
Ein Knotentest ist syntaktisch ein QName, der genau dann erfüllt ist, wenn der Knotenname mit dem Namen des Knotentests übereinstimmt.
Das Prädikat filtert die Ergebnismenge hinsichtlich verschiedener Charakteristika wie Existenz von Kindknoten oder Attributen, Position in der Ergebnismenge, etc.


Das Beispiel zeigt die korrekte XPath-Formulierung zur Lokation aller Qualifikations-Knoten:

Beispiel 3: Hierarchieunabhänigige Knoten-Lokalisierung
Beispiel 60: Hierarchieunabhänigige Knoten-Lokalisierung
XPath-Ausdruck: /ProjektVerwaltung/Person/Qualifikationsprofil//Qualifikation
Ergebnis: <Qualifikation>Programmierung</Qualifikation>
<Qualifikation>Entwickler</Qualifikation>
<Qualifikation>Projektleiterfunktion</Qualifikation>


Durch die abkürzende Schreibweise „//“ entsteht ein Muster zur Selektion aller nachfolgenden Knoten. In Verallgemeinerung dieses Konzepts bietet XPath sog. Achsen an, um relativ zum aktuellen Knoten beliebige Teilbäume zu lokalisieren.
Die Abbildung zeigt die verschiedenen durch Achsen zugänglichen Knotenmengen relativ zum rot hervorgehobenen aktuellen Knoten.

Download der XML-Datei mit dem Beispiel der Graphik

Tabelle  18: XPath-Achsen und ihre Bedeutung
Tabelle 18: XPath-Achsen und ihre Bedeutung
Achse
Semantik
Im Beispiel selektierte Knoten
Graphik
self
Lokalisiert den aktuellen Knoten
Als abkürzende Schreibweise kann der Punkt „.“ verwendet werden.
XPath-Ausdruck:
/node1/node3/node8/self::node8
Ergebnisknotenmenge: {8}

child
Lokalisiert die (direkten) Kindknoten des aktuellen Knotens
XPath-Ausdruck:
/node1/node3/node8/child::*
Ergebnisknotenmenge: {12, 13, 14}

Lokalisiert transitiv alle Kindknoten des aktuellen Knotens, außer Attribut- und Namensraumknoten
XPath-Ausdruck:
/node1/node3/node8/descendant::*
Ergebnisknotenmenge: {12, 13, 14, 15, 16}

descendant-or-self
Lokalisiert transitiv alle Kindknoten des aktuellen Knotens (außer Attribut- und Namensraumknoten), sowie den Knoten selbst
XPath-Ausdruck:
/node1/node3/node8/descendant-or-self::*
Ergebnisknotenmenge: {8, 12, 13, 14, 15, 16}

parent
Lokalisiert den Elternknoten des aktuellen Knotes, falls existent
XPath-Ausdruck:
/node1/node3/node8/parent::*
Ergebnisknotenmenge: {3}

ancestor
Lokalisiert transitiv alle Elternknoten des aktuellen Knotes.
Die ancestor-Achse enthält daher immer den Wurzelknoten, außer der aktuelle Knoten ist es selbst; in diesem Falle liefert die Achse die leere Menge
XPath-Ausdruck:
/node1/node3/node8/ancestor::*
Ergebnisknotenmenge: {1, 3}

ancestor-or-self
Lokalisiert transitiv alle Elternknoten des aktuellen Knotes, sowie den aktuellen Knoten.
Diese Achse enthält immer den Wurzelknoten des Dokuments.
XPath-Ausdruck:
/node1/node3/node8/ancestor-or-self::*
Ergebnisknotenmenge: {1, 3, 8}

preceding
Lokalisiert alle dem aktuellen Knoten vorausgehenden Knoten, ohne seine Vorfahren sowie Attribut- und Namensraumknoten
XPath-Ausdruck:
/node1/node3/node8/preceding::*
Ergebnisknotenmenge: {2, 5, 6, 7}

preceding-sibling
Lokalisiert die im Dokument vor dem aktuellen Knoten auftretenden Geschwisterknoten
XPath-Ausdruck:
/node1/node3/node8/preceding-sibling::*
Ergebnisknotenmenge: {7}

Lokalisiert alle dem aktuellen Knoten nachfolgenden Knoten ohne dessen Kind-, Attribut und Namensraumknoten
XPath-Ausdruck:
/node1/node3/node8/following::*
Ergebnisknotenmenge: {9, 4, 10, 11}

following-sibling
Lokalisiert alle „Geschwister“ des aktuellen Knotens, d.h. Knoten auf derselben Hierarchieebene.
XPath-Ausdruck:
/node1/node3/node8/following-sibling::*
Ergebnisknotenmenge: {9}

attribute
Lokalisiert Attribut(e) eines Knotens
XPath-Ausdruck:
/node1/node3/node8/attribute::*
Ergebnisknotenmenge: {Att1}

namespace
Lokalisiert Namensraum-Attribut eines Knotens
XPath-Ausdruck:
/node1/node3/node8/namespace::*
Ergebnisknotenmenge:
{xmlns:xml="http://www.w3.org/XML/1998/namespace",
xmlns:x="namespace:www.jeckle.de/vorlesung/xml"}



Anmerkung:
Die Achsen ancestor, descendant, following, preceding und self partitionieren ein Dokument (unter Auslassung der Attribut- und Namensraumknoten): sie überschneiden sich nicht und enthalten alle Elementknoten des Dokuments.

Partitionierung eines XML-Dokuments durch XPath-Achsen

Filterung durch Prädikate:
Ein -- durch eckige Klammern abgegrenztes -- Prädikat kann innerhalb jedes Lokalisierungsschrittes eines XPath-Ausdrucks angegeben werden. Fehlt es, wird die bisher ermittelte Knotenmenge nicht modifiziert.
Das Prädikat kann selbst ein gültiger XPath-Ausdruck sein.
Das prinzipielle Vorgehen kann folgendermaßen beschrieben werden:
Beginnend von links nach rechts für jeden Lokalisierungsschritt: (1) Ermittlung der zur Anfrage passenden Knotenmenge
(2) Reduzierung der Ergebnismenge um diejenigen Knoten, für die das Prädikat false liefert.
Befinden sich rechts vom aktuell bearbeiteten Lokalisierungsschritt weitere Ausdrücke, so wird die Resultatmenge als Eingabe eines weiteren Schritts (1) übergeben.

Beispiel 4: Selektion unter Anwendung eines Prädikats
Beispiel 61: Selektion unter Anwendung eines Prädikats
XPath-Ausdruck: //Person[Qualifikationsprofil]/Nachname
Ergebnis:
<Nachname>Obermüller</Nachname>


Der Ausdruck selektiert an beliebiger Stelle des Dokuments („//“) alle Knoten des Typs Person. Die Knotenmenge wird um diejenigen Personen vermindert, zu denen kein Qualifikationsprofil angelegt ist. D.h. Es werden nur diejenigen Knoten selektiert, die über einen Kindknoten des Typs Qualifikationsprofil verfügen. Von dieser Knotenmenge (des Typs Person!) werden anschließend im zweiten Lokalisierungsschritt die Kindknoten des Typs Nachname selektiert.
Mithin liefert der XPath-Ausdruck alle Nachnamen von Personen, zu denen ein Qualifikationsprofil abgelegt ist.
Anmerkung: Das Beispiel nutzt im Prädikat die abkürzende Schreibweise zur Angabe der Vorgabeachse child. Die ausführliche Schreibweise -- mit unveränderter Semantik -- des XPath-Ausdruckes lautet daher: //Person[child::Qualifikationsprofil]/Nachname

Durch die zusätzliche Definition eines Prädikats für den zweiten Lokalisierungsschritt kann eine weitere Filterung der Ergebnismenge realisiert werden. Zusätzlich können innerhalb eines Prädikats neben XPath-Ausdrücken auch einige vordefinierte Funktionen verwendet werden.
Das Beispiel zeigt die Selektion der Vornamen als Kind eines Personen-Knotens (Test der Elternschaft durch erstes Prädikat), wenn dieser mit „O“ beginnt (Test durch starts-with-Funktion innerhalb des zweiten Prädikats). Die Struktur der Eingabedatei zwingt zusätzlich zur Anwendung der following-Achse, da Knoten des Typs Nachname in der Dokumentreihenfolge nach Knoten des Types Vornamen auftreten.

Beispiel 5: Schrittweise Berechnung einer Selektion unter Verwendung mehrerer Prädikate
Beispiel 62: Schrittweise Berechnung einer Selektion unter Verwendung mehrerer Prädikate

XPath-Ausdruck: //Person[parent::ProjektVerwaltung]/Vorname[starts-with(following::Nachname,'O')]

Ausgewerteter XPath://Person
Ergebnis:
<Person PersID="Pers01" mitarbeitInProjekt="Prj01"> ... </Person>
<Person PersID="Pers02" mitarbeitInProjekt="Prj02"> ... </Person>
<Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>

Ausgewerteter XPath://Person[parent::ProjektVerwaltung]
Ergebnis:
<Person PersID="Pers01" mitarbeitInProjekt="Prj01"> ... </Person>
<Person PersID="Pers02" mitarbeitInProjekt="Prj02"> ... </Person>
<Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>

Ausgewerteter XPath://Person[parent::ProjektVerwaltung]/Vorname
Ergebnis:
<Vorname>Hans</Vorname>
<Vorname>Franz</Vorname>
<Vorname>Xaver</Vorname>
<Vorname>Fritz</Vorname>

Ausgewerteter XPath://Person[parent::ProjektVerwaltung]/Vorname[following::Nachname]
Ergebnis:
<Vorname>Hans</Vorname>
<Vorname>Franz</Vorname>
<Vorname>Xaver</Vorname>
<Vorname>Fritz</Vorname>

Ausgewerteter XPath:
//Person[parent::ProjektVerwaltung]/Vorname[starts-with(following::Nachname,'O')]
Ergebnis:
<Vorname>Franz</Vorname>
<Vorname>Xaver</Vorname>



Die durch die XPath-Spezifikation vordefinierten Funktionen lauten in der Übersicht:

Tabelle  19: XPath-Funktionen für Knotenmengen (node-sets)
Tabelle 19: XPath-Funktionen für Knotenmengen (node-sets)
Funktionsprototyp
Funktionalität
number last()
Liefert die Größe der aktuellen Knotenmenge; damit den Index des letzten Elements
number position()
Liefert die Position des aktuellen Knotens innerhalb der Knotenmenge.
Die erste Knoten trägt die Positionsnummer 1.
number count(node-set)
Liefert Elementzahl der übergebenen Knotenmenge
node-set id(object)
Liefert denjenigen Knoten, dessen ID-typisiertes Attribut den Argumentwert aufweist.
Anmerkung: Zur Nutzung dieser Funktion muß zwingend eine Dokument-Grammatik (DTD oder Schema) zum Eingangsdokument vorliegen.
string local-name (node-set?)
Liefert den local name (oder die Menge der Namen) der übergebenen Knotenmenge. Wird keine Knotenmenge übergeben, dann wird der aktuelle Knoten als Argument genutzt.
Liefert die Namensraum-URI der übergebenen Knotenmenge. Wird keine Knotenmenge übergeben, dann wird der aktuelle Knoten als Argument genutzt.
Anmerkung: Handelt es sich nicht um einen Element- oder Attributknoten, so ist die retournierte Zeichenkette leer.
Liefert die QName(n) (=qualifizierte(r) Name(n) aus Namensraumkürzel und local name) der übergebenen Knotenmenge, oder des aktuellen Knotens bei leerer Knotenmenge.
Anmerkung: Nur für Element- und Attributknoten liefert name andere Resultate als local-name.


Tabelle  20: XPath-Funktionen für Zeichenketten
Tabelle 20: XPath-Funktionen für Zeichenketten
Funktionsprototyp
Funktionalität
string string (object)?
Liefert Zeichenkettenrepräsentation einer Knotenmenge.
Dabei wird der Zeichenkettenwert des ersten Knotens in der Dokumentreihenfolge zurückgegeben, andernfalls die leere Zeichenkette.
string concat (string, string, string*)
Verkettet mindestens zwei Zeichenketten.
Liefert true falls string1 das zweite Argument string2 als Präfix enthält; andernfalls false
boolean contains (string1, string2)
Liefert true falls string1 die Zeichenkette aus string2 enthält; andernfalls false.
string substring-before (string1, string2)
Liefert denjenigen Teil der Zeichenkette string1, der sich vor dem ersten Auftreten der Zeichenkette string2 befindet.
string substring-after (string1, string2)
Liefert denjenigen Teil der Zeichenkette string1, der sich nach dem ersten Auftreten der Zeichenkette string2 befindet.
string substring (string, number1, number2?)
Liefert eine Zeichenkette der Länge number2 aus string, beginnend mit der Position number1.
Fehlt das dritte Argument, so wird der Teilstring bis zum Ende der Zeichenkette string zurückgegeben.
Anmerkung: Das erste Zeichen trägt die Indexnummer 1, nicht 0 wie in Java und C üblich.
number string-length(string?)
Liefert die Länge der übergebenen Zeichenkette.
Wird kein Argument übergeben, so wird die Länge des zuvor in eine Zeichenkette konvertierten aktuellen Knotens zurückgegeben.
string normalize-space (string?)
Liefert die übergebene Zeichenkette unter Entfernung führender, schließender und mehrfacher Leerzeichen zurück. Ferner werden noch evtl. in der Argumentzeichenkette enthaltenen Entitätsreferenzen aufgelöst.
Anmerkung: Der Normalisierungsvorgang entspricht damit der Attributwertenormalisierung nach Abschnitt 3.3.3 der XML-Spezifikation.
string translate (string1, string2, string3)
Liefert die Zeichenkette string1 wobei jedes Zeichen aus string2 durch das Zeichen an derselben Position aus string3 ersetzt wurde.


Tabelle  21: Boole'sche XPath-Funktionen
Tabelle 21: Boole'sche XPath-Funktionen
Funktionsprototyp
Funktionalität
boolean boolean (object)
Liefert die Boole'sche Repräsentation des übergebenen Arguments.
Hierbei gilt:
•Eine Zahl wird genau dann nach true konvertiert, wenn sie weder Null (unbeachtlich ihres Vorzeichens) noch eine nicht darstellbare Zahl (NaN) ist.
•Eine Knotenmenge ergibt true, wenn sie nicht leer ist.
•Eine Zeichenkette ergibt true, wenn sie nicht leer (d.h. Länge größer Null) ist.
•Die Konvertierung anderer Typen ist typabhängig, und nicht durch den Standard festgelegt
boolean not (boolean)
Negiert das übergebene Argument
boolean true()
Liefert statisch den Wert true
boolean false()
Liefert statisch den Wert false
boolean lang (string)
Liefert true wenn der aktuelle Knoten ein xml:lang-Attribut gemäß der als Argument übergebenen Sprache besitzt


Tabelle  22: Zahlenorientierte XPath-Funktionen
Tabelle 22: Zahlenorientierte XPath-Funktionen
Funktionsprototyp
Funktionalität
number number (object?)
Konvertiert ein Objekt in eine Zahl gemäß folgender Regeln:
•Eine Zeichenkette wird in eine Fließkommazahl gemäß IEEE 754 konvertiert, wenn sie aus einem optionalen Leerzeichen, gefolgt durch ein optionales Minuszeichen, gefolgt von einem optionalen Leerzeichen und einer Ziffernfolge besteht.
•Der Boole'sche Wert true wird zu 1, der Wert false zu 0 konvertiert.
•Eine Knotenmenge wird zunächst in eine Zeichenkette übersetzt, und dann gemäß der oben definierten Regeln umgesetzt.
•Die Konvertierung anderer Typen erfolgt typabhängig, und ist nicht durch den Standard geregelt.
Wird kein Argument übergeben, so wird stattdessen der aktuelle Knoten als einziges Element einer Knotenmenge interpretiert.
number sum (node-set)
Liefert die Summe aller Elemente der übergebenen Knotenmenge, die zuvor in eine Zahl konvertiert werden.
number floor (number)
Liefert die größte ganze Zahl, die nicht größer als das Argument ist.
Anmerkung: Entspricht dem Abschneiden beliebiger Nachkommastellen
number ceiling (number1)
Liefert die kleinste ganze Zahl, die nicht kleiner als das Argument ist.
Anmerkung: Entspricht floor(number1+0.999...)
number round (number)
Liefert das Argument auf die nächste ganze Zahl gerundet.
Gibt es zwei solche -- wie bei Nachkommastelle gleich 0.5 immer der Fall -- so wird die größere zurückgeliefert.


Für mathematische Berechnungen auf zahlenartigen Knoten stehen folgende Operatoren zur Verfügung.

Tabelle  23: Mathematische Operatoren
Tabelle 23: Mathematische Operatoren
Operator
Funktionalität
+
Addition
-
Subtraktion als zweistelliger Operator.
Der einstellige Operator - ist nicht spezifiziert, er liefert üblicherweise die negative Zahlendarstellung.
*
Multiplikation.
Außer wenn innerhalb von XPath-Ausdrücken als Knotentest eingesetzt.
div
Division
Achtung: Das Symbol / dient ausschließlich als Trennzeichen zur Separierung von Lokalisierungspfaden!
mod
Rest einer ganzzahligen Division


Ein umfangreiches Beispiel: Für das nachfolgende Beispiel wird das Projektverwaltungsdokument erweitert zu:

Beispiel 6: Erweiterte Projektverwaltung
Beispiel 63: Erweiterte Projektverwaltung
(1)<?xml version="1.0" encoding="ISO-8859-15"?>
(2)<ProjektVerwaltung xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="L:\vorlesung\xml\examples\projektverwaltung3.xsd">
(3)	<Person PersID="Pers01" mitarbeitInProjekt="Prj01">
(4)		<Vorname>Hans</Vorname>
(5)		<Nachname>Hinterhuber</Nachname>
(6)	</Person>
(7)	<Person PersID="Pers02" mitarbeitInProjekt="Prj02">
(8)		<Vorname>Franz</Vorname>
(9)		<Vorname>Xaver</Vorname>
(10)		<Nachname>Obermüller</Nachname>
(11)		<Qualifikationsprofil>
(12)			<xhtml:u>IT-Kompetenz</xhtml:u>
(13)			<xhtml:em>verschiedene</xhtml:em> Betriebssysteme und
(14)         <Leistungsstufe>professionelle</Leistungsstufe>
(15)			<xhtml:em>
(16)				<Qualifikation>Programmierung</Qualifikation>
(17)			</xhtml:em>
(18)         verschiedener Programmiersprachen
(19)         <xhtml:em>
(20)				<xhtml:u>
(21)					<Qualifikation>Entwickler</Qualifikation>
(22)				</xhtml:u>
(23)			</xhtml:em> von 1988-1990
(24)         <xhtml:u>
(25)				<Qualifikation>Projektleiterfunktion</Qualifikation>
(26)			</xhtml:u>
(27)         von <xhtml:b>1990-93</xhtml:b> im X42-Projekt in Abteilung AB&amp;C
(28)      </Qualifikationsprofil>
(29)	</Person>
(30)	<Person PersID="Pers03" mitarbeitInProjekt="Prj02">
(31)		<Vorname>Fritz</Vorname>
(32)		<Nachname>Meier</Nachname>
(33)		<Geburtsname value="Huber"/>
(34)	</Person>
(35)	<Projekt ID="Prj01" Projektleiter="Pers01" Mitarbeiter="Pers01"/>
(36)	<Projekt ID="Prj02" Projektleiter="Pers02" Mitarbeiter="Pers03"/>
(37)</ProjektVerwaltung>
Download des Beispiels


Auswertungsschritte

Der XPath-Ausdruck der Abbildung 31 lokalisiert den Attributknoten des Inhalts Prj02.

Übung 2: Einige Übungen
Übung 2: Einige Übungen
Welches Ergebnis liefern folgende XPath-Ausdrücke?
(a) //Person[//child::Qualifikationsprofil]/Nachname
(b) //Person[parent::ProjektVerwaltung]/Vorname[following-sibling::Vorname]
(c) /ProjektVerwaltung/Person[attribute::PersID='Pers01']//Nachname

Wie muß ein XPath-Ausdruck lauten, um folgendes zu selektieren?
(d) Selektion aller Personen mit Nachnamen „Obermüller“.
(e) Selektion aller Nachnamen von Personen die über mehr als eine Qualifikation verfügen.
(f) Selektion der Nachnamen aller Projektleiter.


Anwendungsbeispiel: Integritätsbedingungen in XML-Schema

Die bei der Diskussion des Referenzierungsmechanismus für DTDs geäußerte Kritik gilt prinzipiell auch für die Verwendung von XML-Schema fort. Zwar steht mit XLink ein deutlich flexiblerer Verknüpfungsmechanismus zur Verfügung, jedoch verbleibt das Problem der Gültigkeit von Referenzen. Sie bleibt auch bei der Verwendung von XML-Schema, durch die unverändert von den DTDs übernommene Semantik der Datentypen ID und IDREF, IDREFS, auf das aktuelle Dokument beschränkt. Zusätzlich ist eine Einschränkung, etwa auf den aktuellen Namensraum, nicht möglich. Daher müssen alle Belegungen aller ID-typisierten Attribute zwingend dokumentweit eindeutig sein.

Über die Möglichkeiten der Datentypen hinausgehend bietet XML-Schema das Element unique zur Definition eindeutiger Wertbelegungen an. Hierbei wird auf die Lokatorsprache XPath zurückgegriffen um die abzuprüfenden Knoten innerhalb des Dokuments zu bezeichnen.

Die Syntax verwendet XPath-Ausdrücke eingeschränkter Mächtigkeit sowohl zur Festlegung des der Knotenmenge, auf die sich die Einschränkung bezieht (selector), als auch zur Angabe der eingeschränkten Knoten (field) selbst.

(1)<xsd:unique name="aName">
(2)	<xsd:selector xpath="aValidXPath"/>
(3)	<xsd:field xpath="aFieldStatement"/>
(4)	... 
(5)</xsd:unique>

Die Mächtigkeit der XPath-Ausdrücke ist dahingehend eingeschränkt, daß für das selector-Element ausschließlich Ausdrücke erlaubt sind, die Kindelemente des Knotens liefern, in dessen Kontext die durch unique formulierte Einschränkung angegeben wird. Als Konsequenz ist die Nutzung der verfügbaren XPath-Achsen auf diejenigen beschränkt, die Element-Knotenmengen zurückliefern.
Die Lokationsausdrücke in den -- möglicherweise mehrfach auftretenden -- field-Elementen werden relativ zum Pfad des selector-Knotens interpretiert. Hintereinandergesetzt muß der Pfad eines selector-Elements, gefolgt von einem Pfad eines field-Elements, einen gültigen Lokationsausdruck ergeben, der genau einen Knoten oder genau ein Attribut in der Ergebnismenge liefert. Sind mehrere field-Elemente zu einem selector-Element gegeben, so werden diese als durch logisches und verknüpft interpretiert. Mithin entspricht diese Semantik einem concatenated primary key aus den relationalen Datenbanken.

Das Beispiel zeigt die Nutzung des unique-Konstrukts zur Angabe der Eindeutigkeitsbedingung für das Attribut PersID des Elements Person.
Zunächst selektiert der Pfad /Person alle Knoten des gleichnamigen Typs; durch das field-Element wird die Eindeutigkeitsbedingung auf alle Attribut-Kindnoten des Typs PersID der Knoten in der selektierten Knotenmenge angewendet.
Die Semantik ist damit zur bisherigen ID-Typisierung identisch.

Beispiel 7: Unique-Einschränkung
Beispiel 64: Unique-Einschränkung
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema 
(3)	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
(4)	elementFormDefault="qualified" 
(5)	attributeFormDefault="unqualified">
(6)<xsd:element name="ProjektVerwaltung">
(7)	<xsd:complexType>
(8)		<xsd:sequence>
(9)			<xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/>
(10)			<xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/>
(11)		</xsd:sequence>
(12)		<xsd:attribute name="version" type="xsd:string" fixed="1.0"/>
(13)	</xsd:complexType>
(14)	<xsd:unique name="uniquenessPersID">
(15)		<xsd:selector xpath="Person"/>
(16)		<xsd:field xpath="@PersID"/>
(17)	</xsd:unique>
(18)</xsd:element>
(19)
(20)<xsd:complexType name="PersonType">
(21)	<xsd:attribute name="PersID" type="xsd:token"/>
(22)</xsd:complexType>
(23)
(24)<xsd:complexType name="ProjektType"/>
(25)
(26)</xsd:schema>
Download des Beispiels


Das nächste Beispiel zeigt die Verwendung mehrerer field-Elemente zur Realisierung zusammengesetzter Schlüssel.
Hierzu wird die Kombination aus dem Inhalt des Nachnamen- und des Vornamen-Elements zusammen als eindeutig deklariert.
Überdies zeigt das Beispiel die Anwendung des Schlüsselmechanismus auf Elemente ohne Änderung der Basissyntax, abgesehen von der geänderten XPath-Achse.

Beispiel 8: Zusammengesetzter Schlüssel innerhalb eines unique-Elements
Beispiel 65: Zusammengesetzter Schlüssel innerhalb eines unique-Elements
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema 
(3)	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
(4)	elementFormDefault="qualified" 
(5)	attributeFormDefault="unqualified">
(6)<xsd:element name="ProjektVerwaltung">
(7)	<xsd:complexType>
(8)		<xsd:sequence>
(9)			<xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/>
(10)			<xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/>
(11)		</xsd:sequence>
(12)		<xsd:attribute name="version" type="xsd:string" fixed="1.0"/>
(13)	</xsd:complexType>
(14)	<xsd:unique name="uniquenessPersID">
(15)		<xsd:selector xpath="Person"/>
(16)		<xsd:field xpath="Vorname"/>
(17)		<xsd:field xpath="Nachname"/>
(18)	</xsd:unique>
(19)</xsd:element>
(20)
(21)<xsd:complexType name="PersonType">
(22)	<xsd:sequence>
(23)		<xsd:element name="Vorname" type="xsd:token" minOccurs="1" maxOccurs="unbounded"/>
(24)		<xsd:element name="Nachname" type="xsd:token" maxOccurs="1"/>	
(25)	</xsd:sequence>
(26)</xsd:complexType>
(27)
(28)<xsd:complexType name="ProjektType"/>
(29)
(30)</xsd:schema>
Download des Beispiels


Das Pendant des IDREF(S)-Attributtyps bildet die Kombination der XSD-Elemente key und keyref.
Hierzu lokalisiert key auf der Basis eines XPath-Ausdruckes eine Referenzmenge, während keyref diejenige Knotenmenge lokalisiert, in der ausschließlich Elemente der Referenzmenge enthalten sein dürfen.
Das Beispiel zeigt die Anwendung auf das Element ProjektVerwaltung. Der mit projectKey benannte Schlüssel definiert die Referenzmenge als das Ergebnis der Anfrage Projekt/@ID, worauf die projectReference Bezug nimmt.

Beispiel 9: Schlüsselbasierte Referenzierung
Beispiel 66: Schlüsselbasierte Referenzierung
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsd:schema 
(3)	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
(4)	elementFormDefault="qualified" 
(5)	attributeFormDefault="unqualified">
(6)	<xsd:element name="ProjektVerwaltung">
(7)		<xsd:complexType>
(8)			<xsd:sequence>
(9)				<xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/>
(10)				<xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/>
(11)			</xsd:sequence>
(12)			<xsd:attribute name="version" type="xsd:string" fixed="1.0"/>
(13)		</xsd:complexType>
(14)		
(15)		<xsd:key name="projectKey">
(16)			<xsd:selector xpath="Projekt"/>
(17)			<xsd:field xpath="@ID"/>
(18)		</xsd:key>
(19)		<xsd:keyref name="projectReference" refer="projectKey">
(20)			<xsd:selector xpath="Person"/>
(21)			<xsd:field xpath="@mitarbeitInProjekt"/>
(22)		</xsd:keyref>
(23)	</xsd:element>
(24)	
(25)	<xsd:complexType name="PersonType">
(26)		<xsd:attribute name="mitarbeitInProjekt" type="xsd:token"/>
(27)	</xsd:complexType>
(28)	<xsd:complexType name="ProjektType">
(29)		<xsd:attribute name="ID" type="xsd:token"/>
(30)	</xsd:complexType>
(31)</xsd:schema>
Download des Beispiels


Zusammenfassend lassen sich folgende Vorteile gegenüber dem ID/IDREF-Mechanismus festhalten:

Web-Referenzen 1: Weiterführende Links
Web-Referenzen 12: Weiterführende Links


2.3   Transformation von XML-Dokumenten: XSL Transformations

Die prominenteste Verwendung der XPath-Pfadausdrücke und eine der in jüngerer Zeit am weitesten beachteten XML-Vokabulare dürfte XSLT -- die Sprache der XSL Transformations -- sein. Sie wurde im Verlauf der Standardisierung der Stylesheetsprache XSL von dieser abgetrennt und seither durch eine eigene W3C-Arbeitsgruppe vorangetrieben.
In einem Satz zusammengefaßt stellt sie eine Turing-vollständige funktionale Programmiersprache zur Transformation wohlgeformter XML-Dokumente in beliebige Unicode-Streams -- und damit im speziellen wiederum in XML-Dokumente -- dar.
Der Begriff Transformationen bezeichnet hierbei die Selektion einzelner Bestandteile des Quelldokuments, deren Umordnung sowie die Ableitung neuer Inhalte aus den bereits bestehenden.
Derzeit aktuell ist die Recommendation zur Version 1.0 von Herbst 1999. Intern arbeitet das W3C bereits an der Nachfolgerversion XSLT v2.0, welche auch die absehbaren Entwicklungen des Umfeldes, wie XPath v2.0 oder XML-Schema, berücksichtigen wird.

Jedes XSLT-Stylesheet ist ein gültiges XML-Dokument, in dem alle Elemente der Sprache XSLT im Namensraum http://www.w3.org/1999/XSL/Transform plaziert sind.
Üblicherweise wird der Namensraum an das Präfix xsl gebunden, welches allen XSLT-Sprachelementen explizit vorangestellt wird.
Das Wuzelelement eines XSLT-Dokuments bildet der Knoten stylesheet. Alternativ kann auch transform angegeben werden. Zusätzlich verfügt jedes Stylesheet über ein Versionsattribut zur Bezeichnung der verwendeten XSLT-Version.
Das Beispiel zeigt ein minimales Stylesheet

Beispiel 1: Ein minimales Stylesheet
Beispiel 67: Ein minimales Stylesheet
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
Download des Beispiels


Angewendet auf das Beispieldokument der Projektverwaltung liefert es folgende Ausgabe:

(1)<?xml version="1.0" encoding="utf-8"?>
(2)Hans Hinterhuber       
(3)Franz Xaver Obermüller          
(4)IT-Kompetenz verschiedene Betriebssysteme und professionelle Programmierung verschiedener Programmiersprachen          
(5)Entwickler von 1988-1990 Projektleiterfunktion von 1990-93 im X42-Projekt in Abteilung AB&amp;amp;C  
(6)Fritz Meier

Dies mag zunächst verwundern, definiert doch das Beispiel-Stylesheet keinerlei Transformationsregeln oder Ausgabefunktionen.
Das Ergebnis des minimal-Beispiels wird durch die eingebauten Vorgaberegeln erzeugt. Diese geben, sofern nicht anders angegeben alle Character Information Items unverändert aus.
Durch Überschreiben dieser Vorgaben und die Definition eigener Regeln lassen sich komplexe Transformationen auf dem Eingabedokument verwirklichen.

Transformationsschablonen

Aufbau einer Transformationsschablone

Die Graphik zeigt den Aufbau einer Transformationsschablone. Ihre beiden Hauptbestandteile sind der Lokalisierungspfad und das Ersetzungsmuster.
Der Lokalisierungspfad (in der Spezifikation als pattern bezeichnet) liefert eine Knotenmenge. Als Syntax wird eine eingeschränkte Variante der Lokatorsprache XPath verwendet.
Augenfälligster Unterschied zur bisherigen Notation ist die Optionalität der descendant-Achse (zumeist zu // verkürzt) zur hierarchiebenenunabhängigen Lokalisierung eines Knotens.
Im Rumpf des Musters legt das Ersetzungsmuster diejenige Zeichenfolge fest, die statt jedem Element der lokalisierten Knotenmenge ausgegeben werden soll.
Das nachfolgende Transformationssheet liefert angewandt auf das Projektverwaltungsbeispiel dreimal die Ausgabe Person gefunden!; für jedes Auftreten des Knotens Person in der Eingabe.

Beispiel 2: Eine einfache Transformation
Beispiel 68: Eine einfache Transformation
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)	<xsl:template match="Person">
(6)		<xsl:text>Person gefunden!</xsl:text>
(7)	</xsl:template>
(8)</xsl:transform>
Download des Beispiels
Download der Ergebnisdatei


Innerhalb des Ersetzungsmusters können im Allgemeinen beliebige Textsequenzen angegeben werden. Insbesondere ist die Verwendung wohlgeformter XML-Fragmente zugelassen.
Textsequenzen werden hierbei durch direktes Anschreiben, oder umschlossen durch das Element xsl:text definiert.
Anmerkung: Die Anforderungen an die Wohlgeformtheit sind hierbei auf die korrekte Terminierung der Elemente (damit einhergehend ihre korrekte Schachtelung), sowie die Quotierung der Attribute beschränkt.
Im folgenden Beispiel wird jedes Element des Typs Person durch ein leeres Mitarbeiter-Element ersetzt.
Das Beispiel erklärt auch die übliche Anwendungspraxis, alle XSLT-Elemente durch Namensraumpräfix zu qualifizieren, statt der -- weniger schreibaufwendigen -- Überschreibung des Vorgabenamensraumes. Würde der Vorgabenamensraum mit der Namensraum-URI der XSL-Transformations belegt, so befände sich auch jedes XML-Element und -Attribut innerhalb des Ersetzungsmusters in diesem Namensraum. Als Konsequenz würde der XSLT-Prozessor die Transformation wegen des Auftretens ungültiger (d.h. nicht in der XSLT-Sprache enthaltener) Elemente ablehnen. Bei Redefinition des Vorgabenamensraumes müßte daher für alle Elemente, die nicht Bestandteil von XSLT sind, eine explizite Namensraumdefinition im Element erfolgen, wodurch die Lesbarkeit stark herabgesetzt würde.

Beispiel 3: Erzeugung einer XML-Ausgabe
Beispiel 69: Erzeugung einer XML-Ausgabe
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)<xsl:template match="Person">
(6)	<Mitarbeiter/>
(7)</xsl:template>
(8)
(9)</xsl:transform>
Download des Beispiels
Download der Ergebnisdatei


Erwartungsgemäß liefert das Beispiel dreifach das leere Element Mitarbeiter anstelle der Personen-Elemente der Eingabe.
Die bisher genutzte Form der Ersetzung ist jedoch für die praktische Anwendung in nur äußerst wenigen Fällen geeignet, da sie keine Übernahme von Daten der Eingabedatei in die Ausgabe erlaubt.
Dieses Manko wird durch das XSLT-Sprachelement value-of behoben.

Das Element value-of übernimmt als Teil des Ersetzungsmusters frei selektierbare Text-artige Informationsknoten aus dem Quelldokument. Die Lokalisierung der zu übernehmenden Knoten erfolgt durch XPath-Syntax innerhalb des select-Attributs.
Im folgenden Beispiel wird der Inhalt der Personen-Knoten in den neuen Knotentyp Mitarbeiter übernommen.

Beispiel 4: Übernahme bestehender Information aus dem Quelldokument
Beispiel 70: Übernahme bestehender Information aus dem Quelldokument
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)<xsl:template match="Person">
(6)	<Mitarbeiter>
(7)		<xsl:value-of select="self::*"/>
(8)	</Mitarbeiter>
(9)</xsl:template>
(10)
(11)</xsl:transform>
Download des Beispiels
Download der Ergebnisdatei


Das Resultat liefert jedoch nicht das Quelldokument, unter Umbenennung der Personen-Knoten in Mitarbeiter, sondern die dargestellte Textsequenz.

(1)<?xml version="1.0" encoding="utf-8"?>    
(2)<Mitarbeiter>Hans Hinterhuber</Mitarbeiter>    
(3)<Mitarbeiter>Franz Xaver Obermüller IT-Kompetenzverschiedene Betriebssysteme und professionelle
(4)Programmierung verschiedener Programmiersprachen Entwickler von 1988-1990 Projektleiterfunktion         
(5)von 1990-93 im X42-Projekt in Abteilung AB&amp;amp;C</Mitarbeiter>    
(6)<Mitarbeiter>Fritz Meier</Mitarbeiter>

Die Lösung liegt in der Definition des value-of-Elements. Es konvertiert alle durch den im select-Attribut bezeichneten XPath lokalisierten Knoten in ihre Textrepräsentation. Im vorliegenden Beispiel ist dies der Inhalt der Knoten des Typs Person, der durch den Elementinhalt gebildet wird. Der Elementinhalt wird hierbei durch alle Kindknoten und deren Attribute gebildet.

Zur unveränderten Übernahme eines vollständigen Elements einschließlich der Auszeichnungssymbole wird das XSLT-Element copy-of angeboten.
Das nachfolgende Beispiel modifiziert das vorhergend diskutierte Stylesheet dergestalt, daß für alle Personen-Knoten zunächst ein öffnender Mitarbeiter-Tag gesetzt wird. Im Rumpf des so begonnenen Elements werden durch das copy-of-Element alle Kindknoten der aktuellen Knotenmenge unverändert kopiert.
Als zusätzliche Veränderung gegenüber dem vorigen Beispiel fällt die Nutzung der child-Achse im select-Attribut des copy-of-Elements auf. Dies ist notwendig, da durch den Lokalisierungspfad der Schablone alle Personen-Knoten zu einer Ergebnisknotenmenge zusammengefaßt werden. Die Anwendung der self-Achse innerhalb des copy-of-Elements würde daher auch die Personen-Knoten selbst übernehmen.
Zusammenfassend läßt sich die Funktionalität des Beispiels mit Umbenennung aller Elemente des Types Person in Mitarbeiter wiedergeben.

Beispiel 5: Kopieren vollständiger Elementknoten
Beispiel 71: Kopieren vollständiger Elementknoten
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)<xsl:template match="//Person">
(6)	<Mitarbeiter>
(7)		<xsl:copy-of select="child::*"/>
(8)	</Mitarbeiter>
(9)</xsl:template>
(10)
(11)</xsl:transform>
Download des Beispiels
Download der Ergebnisdatei


Die vorgestellte Transformationsvorschrift ist hinreichend flexibel für Knoten des Typs Person auf beliebiger Hierarchiestufe des Eingabedokuments. Jedoch versagt sie bereits beim Versuch einen weiteren Transformationsschritt einzubauen, der auf einem der unverändert kopierten Kindelemente von Person operiert.
Das folgende Stylesheet stellt einen flexibleren Ansatz zur Umbenennung von einzelnen Knoten vor.

Gegenüber der vorhergehenden Fassung ist der Umfang um zwei weitere template-Elemente erweitert. Eines, das für alle Qualifikationsprofil-Knoten angewendet wird und eines für alle anderen Knoten. Der dort eingesetzte Lokalisierungspfad liefert als Ergebnismenge die Vereinigung aller Attributknoten (attribute::*) mit allen Knoten außer dem Wurzelknoten (node()-Funktion). Im Rumpf des Elements wird das copy-Element zur Kopie jedes Elements verwendet. Anders als das bisher herangezogene copy-of-Element übernimmt diese Variante ausschließlich das aktuelle Element in das Ergebnisdokument und läßt eventuell vorhandene Kindelemente unberücksichtigt.
Das template-Element mit dem Lokalisierungspfad Qualifikationsprofil verfügt über kein Ersetzungsmuster. Es bewirkt damit die Unterdrückung des Teilbaumes unterhalb aller Knoten des Typs Qualifikationsprofil.

Die korrekte Anwendung der verschiedenen Schablonen wird durch den ausführenden XSLT-Prozessor gewährleistet, er ermittelt anhand der Lokalisierungspfade das best-passendste Template und bringt es zur Ausführung. Wenn, wie im vorliegenden Beispiel, mehrere Pfadausdrücke einen Knoten des Eingabedokuments lokalisieren, so wird das am weitesten spezifizierte Muster ausgewählt. Im untenstehenden Beispiel gilt dies für alle Elemente des Typs Person. Jeder dieser Knoten ist sowohl durch den XPath-Ausdruck der ersten Schablone als auch durch den allgemeineren Ausdruck node() zugänglich. Der explizite Pfad Person des ersten Lokalisierungsmusters ist jedoch gegenüber der Ergebnismenge der node-Funktion (deutlich) spezifischer.

Da jeder Knoten, außer denen des Typs Person und Qualifikationsprofil, unverändert in den Ausgabestrom übernommen werden soll, wird im Beispiel wieder ein copy-Element eingesetzt. Im Unterschied zum bisher verwendeten copy-of jedoch mit der Einschränkung, daß copy nur den aktuellen Knoten kopiert und eventuell existierende Kindknoten unberücksichtigt läßt. Dieser Vorgang wird auch als shallow copy bezeichnet.

Steuerung der Transformationsreihenfolge durch apply-templates-Elemente

Standardmäßig durchläuft ein XSLT-Prozessor den aus dem Eingabedokument erzeugten Baum ausgehend vom Wurzelknoten in Preorder Reihenfolge. Während des Traversierungsvorganges werden die zum jeweiligen Knoten „passenden“ Schablonen ausgewertet. „Passend“ deutet hierbei auf das Enthaltensein des besuchten Knotens in der Ergebnismenge eines XPath-Ausdrucks innerhalb eines match-Attributes hin.
Jedoch ist auch die anwenderdefinierte Beeinflussung der vorgegebenen Abarbeitungsreihenfolge möglich. Hierzu enthält das Beispiel zwei apply-templates-Elemente. Diese lösen einen Rekursionsschritt aus, dergestalt, daß an jeder Stelle, an der sich ein apply-templates-Aufruf findet, der Prozessor versucht, weitere passende Schablonen anhand der angegebenen Lokalisierungspfade zu ermitteln. Diese können an der gegebenen Stelle ausgewertet werden. Der Vorgang entspricht damit der Substitution in funktionalen Programmiersprachen.
Im vorliegenden Fall wird nach Ausgabe des öffnenden Tags Mitarbeiter -- nachdem ein Personen-Knoten im Eingabedokument ermittelt wurde -- nach weiteren Knoten im Eingabedokument gesucht, zu denen Lokalisierungspfade in der XSLT-Transformationsvorschrift existieren. Dies ist für alle Attribute und Kindknoten von Person der Fall, da sie durch den Lokalisierungspfad attribute::*|node() zugänglich sind. So wird innerhalb des neu erzeugten Elements Mitarbeiter des Ausgabestroms das Ersetzungsmuster ausgeführt, das die Elemente und Attribute mit ihren Inhalten unverändert übernimmt.
Als Besonderheit nutzt das apply-templates-Element im „allgemeinen“ (dritten) template das Attribut select. Es erlaubt die anwenderdefinierte Steuerung der Menge, innerhalb der nach weiteren passenden Lokalisierungspfaden gesucht werden soll. Standardmäßig ist diese Menge mit allen dem aktuellen Element nachfolgenden (following-Achse) Elementknoten gefüllt. Im vorliegenden Beispiel wird sie durch den XPath des Attributwertes um alle Attributknoten erweitert.

Beispiel 6: Flexible Umbenennung und Löschung von Elementen
Beispiel 72: Flexible Umbenennung und Löschung von Elementen
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)<xsl:template match="Person">
(6)	<Mitarbeiter>
(7)		<xsl:apply-templates/>
(8)	</Mitarbeiter>
(9)</xsl:template>
(10)
(11)<xsl:template match="Qualifikationsprofil"/>
(12)
(13)<xsl:template match="attribute::*|node()">
(14)	<xsl:copy>
(15)		<xsl:apply-templates select="attribute::*|node()"/>
(16)	</xsl:copy>
(17)</xsl:template>
(18)
(19)</xsl:transform>
Download des Beispiels
Download der Ergebnisdatei


Übung 3: Verfolgung der Aufrufreihenfolge
Übung 3: Verfolgung der Aufrufreihenfolge
Lassen Sie sich mit von einem XSLT-Prozessor die Aufrufreihenfolge der einzelnen Templates ausgeben.
Beispielsweise mit dem Prozessor Xalan aus dem Apache-Projekt.


Benannte Ersetzungsschablonen und Parameterübergabe

Neben den Lokationspfad-gesteuerten Schablonen kann der Anwender auch benannte Schablonen, ohne match-Attribut, definieren. Diese werden während der Abarbeitung des Eingabebaumes nicht berücksichtigt, sondern müssen manuell durch call-template aufgerufen werden.
Konzeptionell entsprechen sie Funktionsaufrufen herkömmlicher Programmiersprachen.
(In Spezifikation nachschlagen).
Die Definition erfolgt analog den bisher genutzten Schablonen, mit der Ausnahme, daß statt dem match-Attribut ein eindeutiger Name (Attribute name) angegeben wird.

Als neuer Freiheitsgrad beim nun notwendigen manuellen Aufruf tritt die Möglichkeit der Parameterübergabe hinzu. Als Parameter können beliebige Dokumentbestandteile als Knotenmenge, Ergebnisse von Funktionsausdrücken oder Konstanten übergeben werden.
Eine Parameterrückgabe ist nicht möglich, sie wird durch den Anteil der Schablone an der Ausgabe realisiert.
Die Aufrufsyntax lautet:

(1)<xsl:call-template name="QName">
(2)	<!-- Content: xsl:with-param* -->
(3)</xsl:call-template>
(4)<xsl:with-param name="QName" select="eingeschränkter XPath-Ausdruck">   
(5)	<!-- Content: template --> 
(6)</xsl:with-param> 

Anmerkung: Wie in allen funktionalen Sprachen kommt den Funktionen dieses Typs besondere Bedeutung, als Ausgangspunkt rekursiver Aufrufe, zu.

Die Vorgabe-Transformationsregeln

Das einführende Beispiel dieses Kapitels griff bereits auf die in den XSLT-Prozessor „eingebauten“ Standard-Transformationsvorschriften (built-in templates) zurück.
So lautet die Definition, welche für alle Text- und Attributknoten der Eingabe den Inhalt in die Ausgabe kopiert:

(1)<xsl:template match="text()|@*">
(2)	<xsl:value-of select="."/>
(3)</xsl:template> 

Ferner existiert ein template zur rekursiven Abarbeitung des Eingabebaumes, welches immer dann Anwendung findet, wenn sich keine spezialisiertere Transformationsvorschrift findet.

(1)<xsl:template match="*|/">
(2)	<xsl:apply-templates/> 
(3)</xsl:template>

Ergänzt wird diese Zusammenstellung durch eine Schablone zur Eliminierung von Namensraum- und Kommentarknoten.

Elemente der Ablaufsteuerung

Ähnlich zu herkömmlichen Programmiersprachen bietet auch XSLT Sprachmittel zur Selektion und bedingten Verarbeitung, abhängig von den Eingabedaten.
So erlaubt das if-Element die Bearbeitung der umschlossenen Elemente nur, wenn die im test-Attribut formulierte Boole'sche Bedingung wahr ist.
(In Spezifikation nachschlagen)
Die Syntax lautet:

 <xsl:if test="Boole'scher Ausdruck">   <!-- Content: template --> </xsl:if>

Das Beispiel zeigt die Nutzung des if-Elements. Verfügt ein Knoten des Typs Person über mehr als einen Kindknoten des Typs Vorname so wird der Inhalt des if-Elements abgearbeitet, der durch das XSLT-Element message während des Transformationsvorganges eine Bildschirmausgabe erzeugt.
Diese gibt zunächst den Inhalt des Nachnamen Knotens gefolgt von einem statischen Text aus.
Angewandt auf das Beispieldokument liefert es auf Kommandozeile die Ausgabe: Obermüller hat mehr als einen Vornamen!. Der Inhalt des Eingabedokuments wird unverändert kopiert.

Beispiel 7: Bedingte Verarbeitung durch Verwendung des if-Elements
Beispiel 73: Bedingte Verarbeitung durch Verwendung des if-Elements
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)<xsl:template match="Person">
(6)	<Mitarbeiter>
(7)		<xsl:if test="count(Vorname)&gt;1">
(8)			<xsl:message><xsl:value-of select="Nachname"/> hat mehr als einen Vornamen!</xsl:message>
(9)		</xsl:if>
(10)		<xsl:apply-templates/>
(11)	</Mitarbeiter>
(12)</xsl:template>
(13)
(14)<xsl:template match="Qualifikationsprofil"/>
(15)
(16)<xsl:template match="attribute::*|node()">
(17)	<xsl:copy>
(18)		<xsl:apply-templates select="attribute::*|node()"/>
(19)	</xsl:copy>
(20)</xsl:template>
(21)
(22)</xsl:transform>
Download des Beispiels
Download der Ergebnisdatei


In Erweiterung der simplen Selektion bildet choose die Möglichkeiten einer Mehrfachselektion, oder einer simplen if-then-else-Struktur ab.
(In Spezifikation nachschlagen)
Die Syntax lautet:

(1)<xsl:choose>   
(2)	<!-- Content: (xsl:when+, xsl:otherwise?) --> 
(3)</xsl:choose> 
(4)<xsl:when test="Boole'scher Ausdruck">   
(5)	<!-- Content: template --> 
(6)</xsl:when> 
(7)<xsl:otherwise>   
(8)	<!-- Content: template --> 
(9)</xsl:otherwise>

Das Beispiel zeigt die Transformation des Beispieldokuments in eine XHTML-Ausgabe.
Hierbei wird zunächst der XHTML-Dokumentrahmen bei Auftreten des Dokumentknotens (Suchmuster /) erzeugt. Nach dem öffnenden XHTML-Rumpfelement body werden innerhalb des Quelldokuments wahlfrei weitere, auf eines der angegebenen Suchmuster passende, Knoten gesucht (apply-templates-Aufruf).
Bei Auftreten des Knotens ProjektVerwaltung wird -- nach einigen Überschriftszeilen -- der Kopf einer XHTML-Tabelle, bestehend aus den Elementen table und der Kopfzeile (eingeschlossen durch tr), erzeugt. Den Rumpf der Tabelle schreibt ein anderes Template. Dieses wird jedoch nicht direkt aufgerufen, sondern der Prozeß der Ermittlung neuer „passender“ Knoten neu initiiert; jedoch diesmal, durch das select-Attribut des apply-templates-Elements, nur auf Knoten des Typs Person beschränkt.
Die Ersetzungsregel für Person speichert zunächst den Inhalt des Attributs PersID in einer Variable. Anschließend werden die Tabellenelemente der in der Ersetzungsregel für ProjektVerwaltung geöffneten Tabelle geschrieben. Hierzu werden nacheinander die Ersetzungsmuster für Knoten des Typs Vorname bzw. Nachname, die Kindknoten des aktuellen Knotens sind (die PersID des aktuellen Personen-Knotens findet sich in der zuvor belegten Variable), aktiviert.
Ein zweites Tabellenelement enthält einen XHTML-Hyperlink zu den durch den Mitarbeiter bearbeiteten Projekten. Als Sprungziel wird hierbei der Inhalt des Attributs mitarbeitInProjekt eingetragen.
Das Ersetzungsmuster Vorname übernimmt durch value-of die in einen Zeichenkettenwert gewandelten Inhalte des Elements. Zusätzlich existiert ein zweites Ersetzungsmuster für Knoten des Typs Vorname, das jedoch durch ein Prädikat nur auf das zweite und alle folgenden Elemente dieses Typs angewendet wird. Es gibt vor der Übernahme des Elementinhaltes ein Leerzeichen aus.
Das Element Nachname bettet den Elementinhalt in eine benannte Sprungreferenz ein. Zur Erzeugung der dokumentweiten eindeutigen Benennung wird die Funktion generate-id herangezogen, die für jedes Element des Information Sets des Eingabedokuments einen eindeutigen Bezeichner liefert.
Nach Abschluß der Tabellengenerierung im durch den Lokalisierungspfad ProjektVerwaltung gekennzeichneten Template werden durch den Aufruf des benannten Ersetzungsmusters wasteSpace 25 Leerzeilen, jeweils gefüllt mit der Zeichenkette „...“, erzeugt. Als Besonderheit ist in diesem Muster sehr deutlich die Nutzung der Rekursion zur Modellierung einer Schleife zu sehen.
Zum Abschluß wird nochmals eine Tabelle, nun mit den Mitarbeitern und ihren Projekten, erzeugt.

Beispiel 8: Erzeugung eines XHTML-Reports
Beispiel 74: Erzeugung eines XHTML-Reports
(1)<?xml version="1.0"?>
(2)<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(3)
(4)<xsl:output method="xml" encoding="ISO-8859-1" omit-xml-declaration="no"  indent="yes"
(5)		xmlns="http://www.w3.org/1999/xhtml" />
(6)
(7)<xsl:template match="/">
(8)	<html>
(9)		<head>
(10)			<title>XML-Vorlesung Sommersemester 2001 -- Projektverwaltung</title>
(11)		</head>
(12)		<body>
(13)			<xsl:apply-templates/>
(14)		</body>
(15)	</html>
(16)</xsl:template>
(17)
(18)<xsl:template match="ProjektVerwaltung">
(19)	<center><h1>Projektverwaltung</h1></center>
(20)
(21)	<h2>Projekte</h2>
(22)	<table border="1">
(23)		<tr>
(24)			<td><b>Projektnummer</b></td>
(25)			<td><b>Projektleiter</b></td>
(26)		</tr>
(27)		<xsl:apply-templates select="Projekt"/>
(28)	</table>
(29)
(30)	<pre>
(31)		<xsl:call-template name="wasteSpace">
(32)			<xsl:with-param name="maxLines">25</xsl:with-param>
(33)			<xsl:with-param name="curLines">0</xsl:with-param>
(34)		</xsl:call-template>
(35)	</pre>
(36)
(37)	<h2>Mitarbeiter</h2>
(38)	<table border="1">
(39)		<tr>
(40)			<td><b>Name</b></td>
(41)			<td><b>Projekt</b></td>
(42)		</tr>
(43)		<xsl:apply-templates select="Person"/>
(44)	</table>
(45)</xsl:template>
(46)
(47)	<xsl:template name="wasteSpace">
(48)		<xsl:param name="maxLines"/>
(49)		<xsl:param name="curLines"/>
(50)		<xsl:if test="number($curLines) &lt; number($maxLines)">
(51)<xsl:text>...
(52)</xsl:text>
(53)			<xsl:call-template name="wasteSpace">
(54)				<xsl:with-param name="maxLines"><xsl:value-of select="$maxLines"/></xsl:with-param>
(55)				<xsl:with-param name="curLines"><xsl:value-of select="$curLines + 1"/></xsl:with-param>
(56)			</xsl:call-template>
(57)		</xsl:if>
(58)	</xsl:template>
(59)
(60)<xsl:template match="Projekt">
(61)	<xsl:variable name="prjLeiter" select="@Projektleiter"/>
(62)	<tr>
(63)		<td>
(64)			<xsl:element name="a">
(65)				<xsl:attribute name="name"><xsl:value-of select="@ID"/></xsl:attribute>
(66)				<xsl:value-of select="@ID"/>
(67)			</xsl:element>
(68)		</td>
(69)		<td>
(70)			<xsl:element name="a">
(71)				<xsl:attribute name="href">#<xsl:value-of select="generate-id(//Person[@PersID=$prjLeiter]/Nachname)"/></xsl:attribute>
(72)				<xsl:value-of select="//Person[@PersID=$prjLeiter]/Nachname"/>
(73)			</xsl:element>
(74)		</td>
(75)	</tr>
(76)</xsl:template>
(77)
(78)<xsl:template match="Person">
(79)	<xsl:variable name="persNr" select="@PersID"/>
(80)	<tr>
(81)		<td><xsl:apply-templates select="Vorname[parent::Person/@PersID=$persNr]"/>&#160;
(82)			 <xsl:apply-templates select="Nachname[parent::Person/@PersID=$persNr]"/></td>
(83)		<td>
(84)			<xsl:element name="a">
(85)				<xsl:attribute name="href">#<xsl:value-of select="@mitarbeitInProjekt"/></xsl:attribute>
(86)				<xsl:value-of select="@mitarbeitInProjekt"/>
(87)			</xsl:element>
(88)		</td>
(89)	</tr>
(90)</xsl:template>
(91)
(92)<xsl:template match="Vorname">
(93)	<xsl:value-of select="."/>
(94)</xsl:template>
(95)
(96)<xsl:template match="Vorname[position() &gt; 1]">
(97)	<xsl:text>&#160;</xsl:text><xsl:value-of select="."/>
(98)</xsl:template>
(99)
(100)<xsl:template match="Nachname">
(101)	<xsl:element name="a">
(102)		<xsl:attribute name="name"><xsl:value-of select="generate-id()"/></xsl:attribute>
(103)		<xsl:value-of select="."/>
(104)	</xsl:element>
(105)</xsl:template>
(106)
(107)<xsl:template match="text()"/>
(108)
(109)</xsl:stylesheet>
Download des Beispiels
Download der Ergebnisdatei


Die nachfolgende XSLT-Transformation ermittelt zu jedem beliebigen Element- und Attributknoten (Muster: * bzw. @*) die zugehörige Namensraum-URI (Funktion namespace-uri) und gibt sie gemeinsam mit dem Namen des Knotens (Funktion name) in einer XML-formatierten Ausgabe aus.
Zur Neuselektion aller weiteren Element- und Attributknoten wird apply-templates mit dem Musterausdruck @*|node() ausgeführt, um in die Prüfung nach weiteren passenden Knoten (node()) auch explizit alle beliebigen Attribute (@*) einzubeziehen. Standardmäßig ermittelt apply-templates weitere passende Knoten nur innerhalb der Elemente eines Dokuments.

Beispiel 9: Ausgabe Namensräume jedes Elements und Attributs eines beliebigen XML-Dokuments
Beispiel 75: Ausgabe Namensräume jedes Elements und Attributs eines beliebigen XML-Dokuments
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<xsl:transform version="1.0"
(3)   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
(4)
(5)<xsl:output method="xml" encoding="ISO-8859-1" omit-xml-declaration="no"  indent="yes" />
(6)
(7)<xsl:template match="*">
(8)	<xsl:element name="element">
(9)		<xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
(10)		<xsl:attribute name="namespace"><xsl:value-of select="namespace-uri()"/></xsl:attribute>
(11)	   <xsl:apply-templates select="@*|node()"/>
(12)	</xsl:element>
(13)</xsl:template>
(14)
(15)<xsl:template match="@*">
(16)	<xsl:element name="attribute">
(17)		<xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
(18)		<xsl:attribute name="namespace"><xsl:value-of select="namespace-uri()"/></xsl:attribute>
(19)	   <xsl:apply-templates select="@*|node()"/>
(20)	</xsl:element>
(21)</xsl:template>
(22)
(23)<xsl:template match="text()"/>
(24)
(25)</xsl:transform>
Download des Beispiels


Web-Referenzen 1: Weiterführende Links
Web-Referenzen 13: Weiterführende Links


Übung 4: Textuelle Aufbereitung der Baumstruktur eines XML-Dokuments
Übung 4: Textuelle Aufbereitung der Baumstruktur eines XML-Dokuments
Schreiben Sie eine XSLT-Transformation, die es erlaubt die Elementstruktur beliebiger wohlgeformter XML-Dokumente in Form eines „ASCII-Baums“ (siehe Beispiel) am Bildschirm auszugeben.
Beispiel:
Eingabe:
(1)<root>    
(2)	<childX>       
(3)		<childY1/>       
(4)		<childY2/>    
(5)	</childX>    
(6)	<childX2/> 
(7)</root>
Ausgabe:
(1)root 
(2)+--childX    
(3)	+--childY1
(4)	+--childY2 
(5)+--childX2


2.4   Erzeugung von Präsentationssichten: XML Stylesheets

Mit XML können zwar beliebige Inhalte durch eigene Vokabulare ausgedrückt werden, jedoch bleibt die Präsentationssicht -- zumeist -- unberücksichtigt.
Lediglich für die standardisierte XML HyperText Markup Language (XHTML) ist eine Präsentationssicht eindeutig durch die Semantik der Sprachelemente definiert. Für alle anderen XML-Sprachen gibt es eine solche zunächst nicht, auch wenn einzelne Browser und Anzeigewerkzeuge eine zumeist baumartig orientierte graphische Ansicht bieten.

Zur Erzeugung einer Ansicht eines XML-Dokuments definiert das W3C derzeit die Extensible Stylesheet Language (XSL), eine XML-Sprache zur Formulierung beliebiger Präsentationssichten auf XML-Dokumente.
Dieser Ansatz verfolgt die Linie, Präsentationsinformation und Inhaltsinformation nicht in einem Dokument zu mischen, sondern beide Informationsarten physisch getrennt zu verwalten. Intuitiv wird der Vorzug dieser Idee klar; so können auf denselben Inhalt verschiedene Präsentationssichten angewendet werden, ebenso erlaubt die Abkopplung der Darstellungsinformation deren Wiederverwendung für verschiedenste Inhalte.

Der Gedanke der Trennung von Darstellung und inhaltlicher Information wurde bereits in „späteren“ HTML-Versionen (ab 1996) durch die Cascading Style Sheets (CSS) realisiert. Sie sind, als Ergänzung der HTML, in einer proprietären (d.h. nicht XML) Syntax realisiert um einerseits die Layoutmöglichkeiten von HTML zu erweitern, und zusätzlich wiederkehrende Präsentationsinformation an einem zentralen Ort ablegen zu können.

Konzeptionell teilt sich die XML Stylesheet Language in zwei Bereiche: Eine Transformationssprache und ein XML-Vokabular zur Darstellung von medienunabhängigen Formatierungsanweisungen (formatting objects).
Per Anwendungsszenario sind die beiden Teile eng verknüpft. Die durch XSL definierten Formatierungsobjekte sind ohne Nutzdaten (die zu formatierende Information) weitestgehend nutzlos; die notwendigen Nutzdaten müssen naturgemäß auch als XML-Dokument vorliegen. Die Anreicherung der Nutzdaten um XML-formulierte Formatierungsobjekte reduziert sich somit auf eine Transformation der XML-Nutzdaten in ein XML-Dokument, das neben den (evtl. modifizierten) Nutzdaten auch Formatierungsobjekte enthält.
Wegen ihrer allgemeinen Einsetzbarkeit wurde die Transformationssprache im Laufe des Standardisierungsprozesses vom Formatierungsvokabular abgetrennt, und seither als eigenständiger Standard (XSL Transformations) weiterentwickelt, der im folgenden Kapitel betrachtet wird.
Dieses Kapitel beschränkt sich daher ausschließlich auf die Betrachtung der XSL formatting objects.

Die Abbildung faßt die beiden prinzipiellen Anwendungsszenarien zusammen. Im oberen Teilbild ist die Nutzung von XSL in Verbindung mit einem Dokument einer beliebigen XML-Sprache dargestellt. Als Resultat erzeugt der Browser-interne XSL-Prozessor eine XHTML-Repräsentation, die direkt zur Anzeige gebracht wird. Dieses Szenario wird im direkt anschließenden Kapitel vertieft.
Die untere Bildhälfte zeigt einige der Möglichkeiten der formatting objects für beliebige Zielrepräsentationen, beispielsweise Adobes portable document format (PDF) oder LaTeX. Der in den eingesetzten Prozessor integrierte Transformationsteil erzeugt zunächst die Baumrepräsentation der Zielstruktur, die anschließend zusätzlich durch den XSL formatter in das gewünschte physische Format umgesetzt wird. Diese Komponente übernimmt hierbei die Funktion einer rendering engine.

Anwendungsszenarien der Extensible Stylesheet Language (XSL)

Für XSL-FO existiert keinerlei direkte Browserunterstützung. Dies erklärt sich einerseits in der Komplexität der Spezifikation, deren Umfang die üblichen Darstellungsmöglichkeiten gängiger Web-Browser bei weitem übersteigt und andererseits in dem Hauptanwendungsgebiet des Vokabulars: der (rechnerunabhängigen) Publikation von Texten. Konzeptionell orientiert sich XSL-FO daher eher am klassischem Buchdruck, als an den Cascading Style Sheets.

Geprägt durch das Anwendungsfeld arbeitet XSL-FO generell seitenorientiert. Daher werden die darzustellenden Inhalte gemäß anwenderdefinierter Vorgaben auf die erzeugten Seiten verteilt. Hierzu werden die verschiedenen graphischen Inhalte durch Bereiche (areas) umschlossen.
Die Abbildung zeigt die vier verschiedenen Grundtypen und ihr Verhältnis zueinander.

Die vier XSL-Bereichstypen

Ein Bereich kann entweder block- oder inline-Bereiche enthalten, jedoch nicht beide gleichzeitig. Block-Bereiche stellen die allgemeinste Variante der Inhaltsdarstellung zur Verfügung. Sie definieren einen rechteckigen durch Ränder umschlossenen Bereich zur Aufnahme von Textelementen wie: Absätzen, Überschriften oder Bildunterschriften (in XSL-Spezifikation nachschlagen).
Inline-Bereiche können zur graphischen Hervorhebung der umschlossenen Textbereiche, beispielsweise durch Farbunterlegung, verwendet werden. (in XSL-Spezifikation nachschlagen).
Als Spezialisierung der Block-Bereiche erlauben Line-Bereiche die Darstellung von Texten ohne umgebende Ränder.
Die feinste Darstellungsgranularität offerieren die Glyph-Bereiche, welche genau einen Buchstaben oder ein Zeichen kapseln.

Die nachfolgende Abbildung zeigt einen Bereich, mit einer Anzahl möglicher Attribute, zur Steuerung seiner Positions- und Abstandseigenschaften.
Der mit content rectangle bezeichnete Bereich nimmt die Nutzdaten (einzelner Buchstabe, einzelne Zeile oder mehrzeiliger Text) auf.
Direkt umschließend folgen padding- und border-Bereich.
Durch die Dimensionen von padding kann eine genaue Positionierung des Rahmenbereichs (border) erreicht werden. Optional kann der Rahmenbereich gefüllt oder die Rahmenlinie in verschiedensten Varianten angezeigt werden.
Die space-area definiert einzuhaltende nichtbedruckbare Abstandsflächen zum nächstliegenden plazierten Bereich. Hierdurch lassen sich zu enge Positionierungen oder gar Überschneidungen Verhindern.

XSL-Blockbereich

Struktur eines XSL-FO-Dokuments: Spezifikationsgemäß befinden sich alle Elemente und Attribute eines XSL-FO-Dokuments im Namensraum http://www.w3.org/1999/XSL/Format.
Das Wurzelelement jedes XSL-FO-Dokuments bildet das Element root, es umschließt die einzelnen Definitionen und zu formatierenden Nutzdaten.
Die Spezifikation legt weiter fest, daß im root-Element zwingend die Kindknoten layout-master-set und page-sequence anzugeben sind.
Hierbei enthält das Element layout-master-set eine Art „Schablone“ aller Seiten der zu erzeugenden Ausgabe. Innerhalb dieses Elements werden die Seitenmaße festgelegt, sowie weitere wiederkehrende Regionen dimensioniert. Die nachfolgende Abbildung zeigt diese im Überblick.

Die fünf Regionen einer Standardseite

Innerhalb des zweiten zwingend als Kindelement von root zu spezifizierenden Elements page-sequence werden die einzelnen zu plazierenden Bereiche definiert. Das Element page-sequence nimmt eine Reihe von Seiten auf, beispielsweise ein Kapitel. Die graphische Aufbereitung der Seite wird durch einen page-master oder einen page-sequence-master, der durch das master-name-Attribut referenziert wird, festgelegt. (Informationen zur page-sequence in der XSL-Spezifikation)
Die darzustellenden Inhalte (Text, Tabellen, Graphik, etc.) werden durch flow-Elemente umschlossen. Innerhalb eines flow-Elements sind die verschiedenen Inhaltselemente plaziert.
Das Beispiel zeigt ein erstes formatting objects-Dokument. Der page-master definiert eine DIN A4 Seite mit den bekannten Abmessungen. Ferner wird die Größe des Kopfzeilenbereichs (region-before) auf mindestens (extent-Attribut) 3 cm festgelegt. Dergleichen geschieht für den Fußzeilenbereich (region-after).
Innerhalb der page-sequence, welche die im Seiten-Master festgelegten Dimensionscharakteristika übernimmt (das master-name-Attribut enthält die Identifikation des page-masters), wird innerhalb eines flow-Elements ein Text-block definiert.
Der zentriert gesetzte Text (text-align="center") wird in einer serifenlosen Schrifttype (font-family="sans-serif") der Größe 12 Punkt (font-size="12pt") gesetzt. Zusätzlich wird eine Zeilenhöhe von 15 Punkten (line-height="15pt") mit einem zusätzlichen Abstand von 3 Punkten (space-after="3pt") zum nächst folgenden Element festgelegt.
Als Inhalt des block-Elements ist der darzustellende Text plaziert.

Beispiel 8: Ein erstes XSL-FO-Dokument
Beispiel 76: Ein erstes XSL-FO-Dokument
 <?xml
version="1.0" encoding="utf-8"?> <fo:root
xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="simple"
            page-height="29.7cm"
            page-width="21cm"
            margin-top="1cm"
            margin-bottom="2cm"
            margin-left="2.5cm"
            margin-right="2.5cm">
         <fo:region-body margin-top="3cm"/>
         <fo:region-before extent="3cm"/>
         <fo:region-after extent="1.5cm"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-name="simple">
      <fo:flow flow-name="xsl-region-body">
         <fo:block font-size="12pt"
            font-family="sans-serif"
            line-height="15pt"
            space-after="3pt"
            text-align="center">
               Hello World - mein erstes XSL-FO-Dokument!
         </fo:block>
      </fo:flow>
   </fo:page-sequence>
</fo:root> 
Download des Beispiels
Download der Ergebnisdatei


Textfluß und Objektplazierung
Zur Unterstützung der Erzeugung von Dokumenten mit geänderter Leserichtung, wie im nahen Osten und arabischen Sprachraum üblich, erlaubt XSL-FO ihre explizite Definition durch das Element writing-mode.
Darüberhinaus kann dieses Element auch die Anordnungsreihenfolge der einzelnen Symbole steuern, auf diesem Wege lassen sich auch asiatische Texte -- von „oben nach unten“ -- erzeugen.
Die gültigen Belegungen des writing-modes lauten:

Die drei letzten Belegungen übernehmen den fehlenden Wert von ihrem direkt umgebenden Element.
Die nachfolgende Abbildung zeigt Beispiele der Anwendung des writing-mode-Elements (zum writing-mode in der XSL-Spezifikation nachschlagen).
Man beachte die geänderten Plazierungen der edges! So wird im hebräischen Dokument -- gemäß der getauschten Lesrichtung der Zeilen -- auch die dem Block folgende end-edge links ans Ende(!) des Absatzes verschoben. Dasselbe gilt spiegelsymmetrisch für die start-edge.
Im japanischen Dokument wird die Positionen der start- und after-edge ebenfalls verschoben, um wieder die bekannte Semantik (start-edge geht in Lesrichtung dem Block voraus, after-edge folgt ihm) zu erhalten.

Erzeugung japanischer und hebräischer Texte

Erzeugung von Tabellen
Tabellen werden als blockartige Objekte innerhalb eines flow-Bereichs definiert. Sie stellen ein eigenes Element dar und bedürfen daher keiner Kapselung durch ein block-Element.
Der prinzipiell Aufbau lautet:

 <table>
   <table-column>...</table-column>
   <!-- weitere table-column-Elemente; für jede Tabellenspalte -->
   <table-body>
      <table-row>
         <table-cell>...</table-cell>
         <!-- weitere Tabelleneinträge -->
      </table-row>
   </table-body>
</table> 

table-column legt spaltenspezifische Charakteristika für alle Tabellenzellen der Spalte fest. Hierzu zählt beispielsweise die im angegebenen Code verwende Spaltenbreite; definiert durch das Attribut column-width.
Innerhalb jeder Tabellenzelle stehen wieder alle block-Elemente (Textblöcke, Listen, Tabellen) zur Verfügung.
Das Beispiel nutzt ferner die beiden Attribute border-width und border-style zur Definition der Rahmenlinienstärke bzw. ihres Aussehens.

Beispiel 9: Erzeugung einer Tabelle
Beispiel 77: Erzeugung einer Tabelle
 <?xml
version="1.0" encoding="utf-8"?>

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="myMaster"
                           page-height="29.7cm"
                           page-width="21cm"
                           margin-top="1cm"
                           margin-bottom="2cm"
                           margin-left="2.5cm"
                           margin-right="2.5cm">
      <fo:region-body margin-top="3cm"/>
      <fo:region-before extent="3cm"/>
      <fo:region-after extent="1.5cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>

  <fo:page-sequence master-name="myMaster">
  <fo:flow flow-name="xsl-region-body">
      <fo:block font-size="16pt"
            font-family="sans-serif"
            space-after.optimum="15pt"
            text-align="center">
         Eine Tabelle ...
      </fo:block>

    <fo:table>
      <fo:table-column column-width="50mm"/>
      <fo:table-column column-width="50mm"/>
      <fo:table-column column-width="50mm"/>
      <fo:table-body>
        <fo:table-row>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x11</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x12</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x13</fo:block></fo:table-cell>
        </fo:table-row>
        <fo:table-row>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x21</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x22</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x23</fo:block></fo:table-cell>
        </fo:table-row>
        <fo:table-row>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x31</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x32</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x33</fo:block></fo:table-cell>
        </fo:table-row>
        <fo:table-row>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x41</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x42</fo:block></fo:table-cell>
          <fo:table-cell border-width="0.5mm"           border-style="solid"><fo:block>x43</fo:block></fo:table-cell>
        </fo:table-row>
      </fo:table-body>
    </fo:table>
   </fo:flow>
  </fo:page-sequence>
</fo:root> 
Download des Beispiels
Download der Ergebnisdatei


Einbindung von Graphiken
XSL-FO erlaubt die Einbindung von Graphiken in beliebigen Formaten; die Unterstützung konkreter Formate ist jedoch von der gewählten rendering engine abhängig.
Das nachfolgende Beispiel zeigt die Einbindung einer GIF-Graphik durch das Element external-graphic welches über eine URI die physische Lokation der einzubindenden Bilddatei angibt (in XSL-Spezifikation nachschlagen).
Ferner zeigt das Beispiel die Nutzung des inline-Elements um innerhalb eines Blockes Formatierungsinformation (im Beispiel auf Wortebene) anzubringen.

Beispiel 10: Einbinden einer Graphik
Beispiel 78: Einbinden einer Graphik
 <?xml
version="1.0" encoding="utf-8"?> <fo:root
xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="simple"
            page-height="29.7cm"
            page-width="21cm"
            margin-top="1cm"
            margin-bottom="2cm"
            margin-left="2.5cm"
            margin-right="2.5cm">
         <fo:region-body margin-top="3cm"/>
         <fo:region-before extent="3cm"/>
         <fo:region-after extent="1.5cm"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-name="simple">
      <fo:flow flow-name="xsl-region-body">
         <fo:block font-size="12pt"
            font-family="Helvetica"
            line-height="15pt"
            space-after="3pt"
            text-align="center">
               Text <fo:inline text-decoration="underline">vor</fo:inline> der Graphik ...
         </fo:block>

         <fo:block text-align="center">
            <fo:external-graphic src="file:sblumen.jpg"/>
         </fo:block>

         <fo:block font-size="12pt"
            font-family="Times"
            line-height="15pt"
            space-after="3pt"
            text-align="center">
               Vincent van Gogh: <fo:inline font-style="italic">Sonnenblumen</fo:inline>
         </fo:block>

      </fo:flow>
   </fo:page-sequence>
</fo:root> 
Download des Beispiels
Download der Ergebnisdatei


XSL-FO offenbart sich als mächtiger und flexibler Mechanismus zur Erzeugung auch komplexer Dokumente mithilfe eines XML-Vokabulars. Jedoch zeigen die vorgestellten Beispiele, daß sich die Erstellung der notwendigen XSL-FO-Eingabedokumente mitunter sehr aufwendig gestaltet. Aus diesem Grunde haben sich XML-Sprachen wie das bekannte DocBook entwickelt, durch die diese Komplexität nochmals gekapselt wird. Zusätzlich zu einem vom Schriftsatz abstrahierten Vokabular zur Erzeugung von beliebigen Dokumenten enthält DocBook auch eine Reihe von Transformationsbeschreibungen zur automatisierten Ableitung der XSL-FO-Dokumente. So operiert der DocBook-Verwender mit den Primitiven Kapitel, Überschrift oder Bildunterschrift, die dann durch eine XSLT-Datei nach XSL-FO zur Weiterverarbeitung übersetzt werden.

Web-Referenzen 2: Weiterführende Links
Web-Referenzen 14: Weiterführende Links


2.5   Anfragesprachen

Mit der Sprache XPath wurde im Abschnitt 2.2 ein mächtiger Ansatz zur Lokalisierung beliebiger Knotenmengen innerhalb von XML-Dokumenten vorstellt. Konzeptionell stellt XPath eine durch Pfadausdrücke navigierende Sprache dar. Neben den Vorteilen, insbesondere der vergleichsweise einfachen Formulierung kleiner Anfragen, treten jedoch einige bemerkenswerte Nachteile zu Tage:

  1. Das Ergebnis ist immer eine Element- oder Attributmenge,
    die Konstruktion neuer Ergebnistypen ist nicht möglich.
  2. Dem Anwender muß die Struktur des Eingabedokuments bekannt sein.
  3. Anfragen nach derselben Information müssen für strukturell verschiedene Eingaben i.A. unterschiedlich formuliert werden.
  4. Entstehende Pfadausdrücke gewinnen schnell an Komplexität und damit Unübersichtlichkeit.

Aus diesen Gründen wurden im Laufe der XML-Entwicklung einige Anfragesprachen vorgeschlagen, welche diese Beschränkungen nicht aufweisen. Sammelbecken der verschiedensten Ideen zur Definition einer eigenständigen Anfragesprache für XML-Dokumente war der Tandberg XML Query Workshop 1998. Zahlreiche Hersteller, Forschungsinstitute und Hochschulen legten in Positionspapieren ihre Ideen zur Thematik dar. Hierbei reichte das Spektrum von halbseitigen Anforderungsdefinitionen (eher Wunschzetteln) bis hin zu ausgearbeiteten Sprachvorschlägen (wie XQL). Verständlichermaßen handelte es sich bei den meisten beitragenden Firmen um (bekannte) Hersteller von Datenbankmanagementsystemen, welche eine Anfragesprache für XML als natürliche Erweiterung ihrer (inzwischen durch XML angereicherten) „universellen“ Systeme sehen.
Prinzipiell kann jedoch eine XML-Anfragekomponente auf beliebigen XML-Eingaben, also auch auf reinen Dokumenten, operieren.

Anders als die in der XPath-Recommendation definierten Pfadausdrücke legen die vorgeschlagenen Anfragesprachen keine navigierenden Zugriffe zugrunde, sondern orientieren sich an den klassischen deskriptiven Anfragesprachen wie SQL.
Durch die unerwartet große Resonanz des Tandberg-Workshops motiviert initiierte das W3C die XML Query Working Group und beauftragte diese mit der Erarbeitung eines Sprachstandards, der mittlerweile als „XQuery“ in einem ersten Arbeitsstand (working draft) vorliegt.
Nachfolgend soll diesem zukünftigen Sprachstandard die Hauptaufmerksamkeit gewidmet werden. Betrachtungen anderer Anfragesprachen finden nur insofern statt, wie sie für das Verständnis von XQuery notwendig und dienlich sind.

Neben der Behebung der erwähnten Nachteile einer Pfad-basierten Anfrage wurden folgende Anforderungen an XQuery definiert:

Die Abbildung stellt die Vorläufer, Entwicklungen und Einflüsse, die in die W3C-Initiative mündeten, dar.
Konzeptionell stellt sich XQuery, als deklarative Sprache und auch syntaktisch, in die Tradition der in den relationalen Datenbanken implementierten Sprache SQL; genaugenommen deren Anfrageteil der bekannten SELECT ... FROM ... WHERE ...-Struktur.
Die Berücksichtigung von SQL geht auf den Sprachvorschlag XML-QL zurück. Neben der Deklarativität weist XQuery eine funktionale Struktur auf, welche die beliebige Kombination von Teilausdrücken zu einer Anfrage erlaubt. Hierfür stand der ODMG-Sprachstandard OQL zur Anfrage auf objektorientierte Datenbanken Pate. Auch er hat sich als deklarative Anfragesprache aus SQL heraus entwickelt.
XQL markiert eine alternative Entwicklungslinie zur Formulierung der XML-Anfragesprache, sie entwickelt im wesentlichen die Pfadausdrücke der XPath-Syntax fort. Damit greift XQL frühere Entwicklungen aus dem Umfeld semi-strukturierter Datenverwaltung -- wie Lorel oder UnQL -- auf.
Beide Sprachstämme, sowie experimentelle Prototypen wie „YATL“, flossen in den Sprachvorschlag Quilt ein, der durch die W3C-Arbeitsgruppe zu XQuery weiterentwickelt wird.

Vorläufer der Anfragesprache XQuery

Nicht zuletzt wegen der besseren Optimierbarkeit algebraisch fundierter Ausdrücke ist XQuery im Stile SQLs als deskriptive Anfragesprache realisiert. Dieser Sprachtyp definiert Bedingungen, denen ein gültiges Ergebnis genügen muß, läßt jedoch die Realisierung der Anfrageverarbeitung durch das System vollkommen offen. Hierunter sind insbesondere Auswertungsreihenfolge, Zugriffspfade und optimierende Techniken wie Indexstrukturen, etc. zu verstehen.
Die Abbildung 39 zeigt (angeleht an K. Dittrich) das Prinzip deskriptiver Anfragen. Gelb dargestellt ist die Menge der möglichen XML-Dokumentinstanzen. Diese werden durch das zugrundeliegende Schema bestimmt. In der Praxis existiert eine -- rot symbolisierte -- Untermenge tatsächlich verwalteter Dokumente, die konform zum Schema formuliert sind.
Jede Anfrage (grünes Rechteck) beschreibt eine zweite Untermenge der gültigen Dokumentinstanzen. Anschaulich handelt es sich hierbei um diejenigen Dokumente, die die in der Anfrage formulierten Bedingungen erfüllen.
Innerhalb der Schnittmenge aus existierenden Dokumenten und prinzipiell „passenden“ Dokumentinstanzen befindet sich das Anfrageergebnis. Mithin diejenigen verwalteten Daten, die den Anfragebedingungen genügen.
Da die Menge der durch die Anfrage beschriebenen Dokumentinstanzen leer sein kann -- dies ist bei a priori „unmöglichen“ Anfragen (etwa: „Zeige alle Dokumente, deren Element mit dem Namen X gleichzeitig Y heißt“) der Fall -- muß sich nicht zwingend eine (nichtleere) Ergebnismenge ergeben. Die tatsächlich existierenden Dokumentinstanzen bilden lediglich bei Anfrageausführung auf XML-Dokumenten eine nichtleere Menge, da leere XML-Dokumente gemäß den Anforderungen an die Wohlgeformtheit nicht zulässig sind. Im Falle der Anfrageauswertung gegen die Inhalte einer XML-Datenbank -- XQuery spricht hierbei von virtuellen Dokumenten -- kann auch diese Eingangsmenge (bei unbefüllter Datenbank) leer sein.

Prinzip deskriptiver Anfragen

Syntax einer XQuery-Anweisung:
Die Struktur einer XQuery Anweisung wird durch die FLWR- (sprich flower) Syntax beschrieben. Sie entspricht in ihrer Mächtigkeit der XQuery-Algebra. Syntaktisch verkörpert sie jedoch keineswegs die einzige Möglichkeit XQuery-Anfragen zu formulieren. Genaugenommen stellt die FLWR-Syntax nur eine Empfehlung einer möglichen Algebradarstellung vor. Weitere Syntaxen können jederzeit durch den Anwender definiert werden. Das W3C-Dokument XML Syntax for XQuery definiert beispielhaft eine XML-Syntax zu XQuery.

 FLWRExpr    ::=  (ForClause | LetClause)+ WhereClause? "return" Expr
ForClause ::= "for" Variable "in" Expr ("," Variable "in" Expr)*
LetClause ::= "let" Variable ":=" Expr ("," Variable ":=" Expr)*
WhereClause ::= "where" Expr Expr ::= extended XPath

Die entstehenden Ausdrücke sind durch das Auftreten der definierten Schlüsselworte FOR, LET, WHERE und RETURN strukturiert, die namensgebend für den Gesamtausdruck sind.
Nachfolgend werden ausgewählte Sprachbestandteile an Beispielen vorgestellt.

Beispiel 79 zeigt einen ersten XQuery-Ausdruck, der eine Menge vorgegebener Elemente umstrukturiert. Mittels der FOR-Klausel werden alle in der durch runde Klammern begrenzten Aufzählungsmenge angegebenen Elemente des Namens Nachname an die Variable name gebunden. Die RETURN-Klausel gibt die gebundenen Werte einzeln aus und bettet sie statisch in ein Element Mitarbeiter ein.
Im Ergebnis treten daher nicht nur die textuellen Wertinhalte der Nachnamen-Elemente innerhalb der durch die Abfrage erzeugten Mitarbeiter-Elemente auf, sondern die gesamten Nachname-Elemente einschließlich ihrer Start- und Endemarken.

Beispiel 11: Selektion mit der FOR-Klausel aus einer Menge (explizit) vorgegebener Werte
Beispiel 79: Selektion mit der FOR-Klausel aus einer Menge (explizit) vorgegebener Werte
(1)FOR $name IN 
(2)	(<Nachname>Hinterhuber</Nachname>, <Nachname>Obermüller</Nachname>,
(3)	<Nachname>Meier</Nachname>)
(4)RETURN
(5)<Mitarbeiter>
(6){$name}
(7)</Mitarbeiter>
Download des Beispiels
Download der Ergebnisdatei


Üblicherweise werden jedoch die abzufragenden Werte nicht explizit durch den Anfragenden vorgegeben, sondern werden im Verlauf der Anfrageauswertung durch den XQuery-Prozessor aus einem oder mehreren Dokumenten extrahiert.
Daher liegt den nachfolgenden Anfragebeispielen, sofern nicht anders angegeben das Projektverwaltungsdokument zugrunde.

Beispiel 12: XQuery-Anfrage (FR) die alle Personen liefert
Beispiel 80: XQuery-Anfrage (FR) die alle Personen liefert
(1)FOR $x IN document("projektverwaltung5.xml")//Person
(2)RETURN $x 
Download des Beispiels
Download der Ergebnisdatei


Der Ausdruck des Beispiels 80 liefert alle Knoten des Typs Person. Hierzu werden eine oder mehrere durch XPath definierte Knotenmengen an Variablen gebunden. Im Beispiel ist dies die durch den erweiterten XPath //Person erreichbare Knotenmenge, die an die neu definierte Variable $x gebunden und im Anschluß durch das RETURN-Schlüsselwort ausgegeben wird.

Beispiel 13: XQuery-Anfrage der Form FWR
Beispiel 81: XQuery-Anfrage der Form FWR
(1)FOR $y IN document("projektverwaltung5.xml")//Person 
(2)WHERE $y/Vorname = 'Hans' 
(3)RETURN $y/Nachname
Download des Beispiels
Download der Ergebnisdatei


Die Anfrage des Beispiels 81 erweitert den vorhergehenden Ausdruck zunächst um eine WHERE-Bedingung. Sie prüft innerhalb der durch die Variablen $y repräsentierten Knotenmenge die Elemente des Typs Vorname auf den Inhalt Hans.
Für alle Knoten aus $y die diese Bedingung erfüllen, liefert die Anfrage das Element Nachname.

Ist eine sortierte Ausgabe der Resultate gewünscht, so kann der RETURN-Klausel ein Sortierausdruck der Form SORTBY (Knotenmenge ascending|descending) nachgestellt werten.
Beispiel 82 zeigt dies als modifizierte Erweiterung der vorhergehend diskutierten Anfrage.

Beispiel 14: Sortierung der Resultatmenge
Beispiel 82: Sortierung der Resultatmenge
(1)FOR $y IN document("projektverwaltung5.xml")//Person 
(2)RETURN $y/Nachname
(3)SORTBY (Nachname ascending)
Download des Beispiels
Download der Ergebnisdatei


Beispiel 15: XQuery-Anfrage der Form FLWR
Beispiel 83: XQuery-Anfrage der Form FLWR
(1)FOR $personen IN document("projektverwaltung5.xml")//Person 
(2)LET $projekte := document("projektverwaltung5.xml")//Projekt 
(3)WHERE $projekte/@Projektleiter = $personen/@PersID 
(4)RETURN $personen/Vorname
Download des Beispiels
Download der Ergebnisdatei


Beispiel 83 zeigt eine Anfrage unter Ausprägung aller vier Strukturelemente. Die Anfrage ermittelt die Vornamen aller Projektleiter.
Hierbei wird zunächst die zu durchsuchende Knotenmenge //Person an die Variable $personen gebunden. Innerhalb des LET-Blockes wird zusätzlich die Variable $projekte mit der durch den XPath erreichbaren Knotenmenge //Projekt identifiziert. Durch die WHERE-Klausel werden alle diejenigen Knoten in $personen selektiert, deren PersID-Attribut mit dem Inhalt eines Projektleiter-Attributs in $personen übereinstimmt.
Zurückgeliefert werden durch RETURN alle Vorname-Elemente aus $personen.
Der wesentliche Unterschied zwischen den in FOR- und den in LET-Strukturen auftretenden Knotenmengen liegt in ihrer Behandlung während der iterativen Abarbeitung der Anfrage. Während alle in FOR referenzierten Knoten durchlaufen werden, wird die LET-Knotenmenge zu Beginn der Auswertung statisch ermittelt und keine Iteration über sie durchgeführt.
Beispiel 84 zeigt nochmals gesondert die verschiedene Auswertungssemantik von FOR und LET ohne dabei auf die Projektverwaltung als Eingabedokument zurückzugreifen.

Beispiel 16: Auswertung der FOR- und LET-Klausel
Beispiel 84: Auswertung der FOR- und LET-Klausel
(1)FOR $NName in (<Nachname>Huber</Nachname>, <Nachname>Müller</Nachname>, <Nachname>Meier</Nachname>)
(2)LET $VName := (<Vorname>Hans</Vorname>, <Vorname>Franz</Vorname>, <Vorname>Fritz</Vorname>)
(3)RETURN 
(4)<Person>
(5)	<Name>
(6)		{$VName}
(7)		{$NName}
(8)	</Name>
(9)</Person>
Download des Beispiels
Download der Ergebnisdatei


Im Verlauf der Anfrageauswertung werden zunächst die drei Nachnamen-Elemente iterativ an die Variable NName gebunden, d.h. in jedem Durchlauf der Auswertungsschleife wird genau ein Wert NName zugewiesen. Die Berechnung eines Ergebnisses für NName erfolgt also in jedem Teildurchlauf der Auswertung. Anders gelagert ist das Verhalten von LET. Das Ergebnis dieser Klausel wird nur einmal innerhalb der Abfrage bestimmt und an die Variable VName gebunden, daher enthält VName auch nicht einen Einzelwert, sondern die Menge aller zugewiesenen Werte.
Das Ergebnis spiegelt dieses Verhalten wieder, es enthält nicht, wie intuitiv zu vermuten die paarweise Zuordnung der Werte, sondern das Kartesische Produkt der Menge der Nachnamen mit der als einelementiger Menge betrachteten Nachnamensammlung.

Um mehr als eine Knotenmenge iterativ bearbeiten zu können darf ein XQuery-Ausdruck mehrere FOR-Klauseln beinhalten. Das folgende Beispiel zeigt auf diesem Wege die (korrekte) Berechnung des kartesischen Produktes der in Beispiel 84 dargestellten Namen.

Beispiel 17: Berechnung des kartesischen Produktes zweier Mengen
Beispiel 85: Berechnung des kartesischen Produktes zweier Mengen
(1)FOR $NName in (<Nachname>Huber</Nachname>, <Nachname>Müller</Nachname>, <Nachname>Meier</Nachname>)
(2)FOR $VName in (<Vorname>Hans</Vorname>, <Vorname>Franz</Vorname>, <Vorname>Fritz</Vorname>)
(3)RETURN 
(4)<Person>
(5)	<Name>
(6)		{$VName}
(7)		{$NName}
(8)	</Name>
(9)</Person>
Download des Beispiels
Download der Ergebnisdatei


Auswertungsreihenfolge einer XQuery-Anfrage: In den Beispielen klingt bereits die Auswertungsreihenfolge der einzelnen Anweisungsteile an, sowie die zwischen den Einzelschritten transportierte Information.
Die Berechnung des Ergebnisdokuments erfolgt in Reihenfolge der verschiedenen Klauseln. In einem ersten Schritt werden die Knotenmengen der innerhalb von FOR- und WHERE-Klauseln auftretenden erweiterten XPath-Ausdrücke ermittelt. Die an Variablen gebundenen Knoten werden anschließend um diejenige Teilmenge vermindert, welche die in der WHERE-Klausel formulierte Bedingung nicht erfüllen.
Nach Errechnung des Typs des Zielschemas wird das Anfrageergebnis als XML-Dokument zurückgeliefert.
Abbildung 40 veranschaulicht dies.

Informationsfluß und Abarbeitungsreihenfolge einer XQuery-Anfrage

Einige Beispiele:
Die Anfrage aus Beispiel 86 entspricht in Aufgabe und Ergebnis dem XPath-Ausdruck aus Beispiel 58. Geliefert werden -- unter Erhalt der Reihenfolge ihres Auftretens im Eingabedokument -- alle Vornamen zu jedem Knoten des Typs Person.

Beispiel 18: XQuery-Anfrage zur Ermittlung aller Vornamen
Beispiel 86: XQuery-Anfrage zur Ermittlung aller Vornamen
(1)FOR $x IN document("projektverwaltung5.xml")//Person 
(2)RETURN $x/Vorname
Download des Beispiels


Die Anfrage aus Beispiel 87 entspricht dem XPath-Ausdruck des Beispiels 59 bzw. der hierarchieebenenunabhängigen Formulierung aus Beispiel 60.
Demnach ergibt sich die vermeintlich kompaktere Darstellung der XQuery-Anfrage gegenüber dem Pendant aus Beispiel 59 allein aus der Nutzung der descendant-Achse aus XPath.

Beispiel 19: XQuery-Anfrage zur Hierarchiebenenunabhängigen Anfrage
Beispiel 87: XQuery-Anfrage zur Hierarchiebenenunabhängigen Anfrage
(1)FOR $x IN document("projektverwaltung5.xml")//Qualifikation 
(2)RETURN $x
Download des Beispiels
Download der Ergebnisdatei


Die in Beispiel 88 formulierte Anfrage gewinnt hingegen durch die erfolgte Separierung von Bedingung und Lokalisierungspfad deutlich an Übersichtlichkeit gegenüber der XPath-Formulierung gleicher Funktion.
Zusätzlich entsteht durch die Konzentration aller Bedingungen in die WHERE-Klausel Optimierungspotential vor Durchführung der Anfrage, das in der durch die nagivierende Schreibweise der XPath-Syntax nicht gegeben war.

Beispiel 20: Bedingte Selektion in XQuery
Beispiel 88: Bedingte Selektion in XQuery
(1)FOR $x IN document("projektverwaltung5.xml")//Person 
(2)WHERE $x//Qualifikationsprofil 
(3)RETURN $x//Nachname
Download des Beispiels
Download der Ergebnisdatei


Noch deutlicher zeigt sich gewonnene Übersichtlichkeit bei der Reformulierung des Beispiels 62.
Darüberhinaus erweist sich die Möglichkeit, Kontexte durch LET-Klauseln explizit zu bilden und zu benennen, deutlich der impliziten Formulierung in XPath überlegen:

Beispiel 21: Selektion hinsichtlich mehrerer Bedingungen in XQuery
Beispiel 89: Selektion hinsichtlich mehrerer Bedingungen in XQuery
(1)FOR $x IN document("projektverwaltung5.xml")//Person 
(2)LET $y := $x/Vorname/following::Nachname 
(3)WHERE $x/parent::ProjektVerwaltung and starts-with($y,'O') 
(4)RETURN $x/Vorname
Download des Beispiels


Dasselbe Bild gibt auch Beispiel 90 wieder; die mehrschrittige, mit Prädikaten zweiter Ordnung formulierte, XPath-Formulierung läßt sich durch eine äquivalente XQuery-Anfrage ersetzen.
Auch in diesem Beispiel erweist sich die Möglichkeit der gleichzeitigen Operation auf mehreren benannten Knotenmengen als sehr hilfreich.

Beispiel 22: XQuery des umfangreichen XPath-Beispiels
Beispiel 90: XQuery des umfangreichen XPath-Beispiels
(1)FOR $x IN document("projektverwaltung5.xml")//Person 
(2)LET $y := $x//Nachname 
(3)WHERE count($x/Vorname) = 1 and $y//Geburtsname/@value != '' 
(4)RETURN $x/@mitarbeitInProjekt 
Download des Beispiels
Download der Ergebnisdatei


Eine der abzusehenden Besonderheiten im noch nicht verabschiedeten XQuery-Standard ist die Nutzung von Schemainformation, falls vorhanden, zur Steigerung der Mächtigkeit der Anfragesprache.
Hervorstechendstes Beispiel dürfte die Auswertung der ID-IDERF(S)-Beziehungen sein, die innerhalb XPath gleichgestellt den CDATA-typisierten Attributen behandelt wurden.
Beispiel 91 zeigt dies anhand der Beziehung zwischen Projekt und den dort eingesetzten Mitarbeitern. Inhaltlich läßt sich diese Beziehung an der Korrespondenz der Belegung des Attributs Mitarbeiter mit Werten, die zuvor bereits innerhalb eines Person-Elements im Attribut PersID angegeben wurden, festmachen.
XQuery definiert einen Operator =>, der Entsprechungen zwischen IDREF(S) und ID-typisierten Attributen auswertet. Formal kann dieser Operator beschrieben werden als:
=> := (e1 : xsd:IDREF(S), e2 : xsd:ID) --> xsd:boolean
Er liefert true wenn für die linksstehende Referenz(-menge) ein entsprechend belegtes ID-typsiertes Attribut existiert, andernfalls false. Die verwendeten Typen entsprechen denen der XML-Schema Part 2 Recommendation.

Beispiel 23: XQuery mit Dereferenzierung von IDREF(S)-Attributen
Beispiel 91: XQuery mit Dereferenzierung von IDREF(S)-Attributen
(1)FOR $x IN document("projektverwaltung5.xml")//Person 
(2)LET $y := document("projektverwaltung5.xml")//Projekt 
(3)WHERE $y/@Mitarbeiter => $x/@PersID 
(4)RETURN $x/Vorname 
Download des Beispiels


Erweiterung der XQuery-Basisfunktionalität:
Durch die Definition eigener Funktionen kann der Ausgangssprachumfang von XQuery durch den Anwender erweitert werden. Diese Funktionen stehen ab ihrer Definition für die Verwendung in Abfragen zur Verfügung.
Beispiel 92 zeigt die Definition der Funktion get_vorname die zu einem gegebenen textuellen Elementinhalt die im Dokument abgelegten Vornamen-Elemente liefert.

Beispiel 24: Erweiterung der XQuery-Mächtigkeit um eigene Funktionen
Beispiel 92: Erweiterung der XQuery-Mächtigkeit um eigene Funktionen
(1)DEFINE FUNCTION get_vorname (ELEMENT $nachname) RETURNS ELEMENT
(2){
(3)	FOR $x IN document("projektverwaltung5.xml")//Person
(4)	WHERE $x/Nachname = $nachname
(5)	RETURN $x/Vorname
(6)}
(7)
(8)<Namensliste>
(9){ get_vorname(document("projektverwaltung5.xml")//Nachname) }
(10)</Namensliste>
Download des Beispiels
Download der Ergebnisdatei


Innerhalb einer XQuery-Funktion können vollständige XQuery-Ausdrücke aber auch einfache prozedurale Berechnungsvorschriften angegeben sein. Vor diesem Hintergrund führt Beispiel 93 die Berechnung der Fakultät der Zahl 42 als XQuery-Funktion ein.

Beispiel 25: Berechnung der Fakultät einer Zahl als XQueryfunktion
Beispiel 93: Berechnung der Fakultät einer Zahl als XQueryfunktion
(1)Define FUNCTION fac (INTEGER $n) RETURNS INTEGER
(2){
(3)IF ($n = 0)
(4)THEN 1
(5)ELSE $n * fac($n - 1)
(6)}
(7)<p>
(8){ fac(42) }
(9)</p>
Download des Beispiels
Download der Ergebnisdatei


Berechnung des Zielschemas:
Wie anhand des =>-Operators im vorhergehenden Beispiel veranschaulicht, definiert XQuery für alle Operationen eine formale Semantik -- sie entspricht der Algebra --, die zur Berechnung des Zielschemas verwendet wird. Das zugrundeliegende Typsystem ist an das aus XML-Schema bekannte angelehnt, wenngleich es ihm nicht vollständig entspricht. Die verwendete mathematische Formalisierung des XSD-Typsystems ist im Dokument XML Schema: Formal Description ausführlich beschrieben und soll hier nicht vertieft werden.
Als Beispiel sei die formale Semantik der conditional expression herausgegriffen. Sie ist in Abschnitt 3.3 des XQuery-Dokuments beschrieben als:

Formale Semantik einer conditional expression

Hieraus ergibt sich der Ergebnistyp eines solchen Ausdrucks, wie intuitiv erwartet, als Typ einer der beiden Alternativen (im Formalismus der Abbildung 41 als t1 und t2).

Insgesamt zeigt sich XQuery als mächtige und, insbesondere für Anwender mit Vorwissen aus dem Bereich der Anfragesprachen für relationale oder objektorientierte Datenbanken, leicht zu erlernende Sprache.
Hervorgehoben sei abschließend, daß XQuery keineswegs die Pfadausdrücke nach XPath ersetzen wird, sondern vielmehr XPath im praktischen Einsatz auf seinen eigentlichen Zweck -- die Formulierung von navigierenden Pfadausdrücken -- reduziert werden kann.
Die Tabelle 24 stellt die Charakteristika der XML-Anfragespache, klassischer Anfragesprachen und der XML-Pfadausdrücke zusammen. Die Übersicht wurde inspiriert durch P. Fankhauser.

Tabelle  24: Übersicht verschiedener Anfragesprachen hinsichtlich ihrer Einsatzbereiche
Tabelle 24: Übersicht verschiedener Anfragesprachen hinsichtlich ihrer Einsatzbereiche
Sprache
Eingangsdaten
Ausgangsdaten
Schema
Anwendungsbereich
XPath und Muster aus XSLT
XML
Unicode Text oder XML
XML-DTDs oder -Schema
(wird jedoch nicht ausgewertet)
Dokumenttransformationen
SQL, OQL
strukturierte typisierte Information
(Re-)Strukturierte typisierte Information
SQL-DDL, ODL
Auswertung von Datenbankinhalten
(relational oder postrelational)
XQuery
XML
XML
XML-Schema
XML-Datenbanken, Anfrage an Dokumente


Web-Referenzen 3: Weiterführende Informationen
Web-Referenzen 15: Weiterführende Informationen


Übung 5: Einige Übungen
Übung 5: Einige Übungen
Welches Ergebnis liefern folgende XQuery-Anfragen?
(a) FOR $x IN //Person
WHERE $x//Qualifikationsprofil
RETURN $X//Nachname
(b) FOR $x IN //Person
WHERE count($x/Vorname) > 1
RETURN $x/Vorname
(c) FOR $X IN //Person
WHERE $x/@PersID = 'Pers01'
RETURN $x/Nachname


Wie muß eine XQuery-Anfrage lauten, die folgendes liefert?
(d) Selektion aller Personen mit Nachnamen „Obermüller“.
(e) Selektion aller Nachnamen von Personen, die über mehr als eine Qualifikation verfügen.
(f) Selektion der Nachnamen aller Projektleiter.


2.6   Der erste Schritt zum Semantic Web: Das Resource Description Framework

Der nächste Evolutionsschritt des Internets soll durch die Weiterentwicklung des heutigen sichtbaren Webs zu einem allgegenwärtigen und „unsichtbaren“ Kommunikationsmedium gekennzeichnet sein. Das zukünftige Web soll daher neben dem Informationsaustausch von Mensch zu Mensch vor allem der Interkation zwischen Maschinen dienen. Notwendige Voraussetzung hierfür ist die Erweiterung der heute verfügbaren Web-Inhalte um semantische Information, die ausdrücken was Inhalte bedeuten (sollen).

Tim Berners-Lee, James Hendler und Ora Lassila formulieren in die Zielsetzung des Semantischen Webs lakonisch als eine Erweiterung des gegenwärtigen Webs, in der Information über eine wohldefinierte Bedeutung verfügt, um eine bessere Zusammenarbeit zwischen Mensch und Computer zu ermöglichen. Unterstellt man der Formulierung gegenwärtiges Web die Bedeutung eines zusammenfassenden Begriffs als Gesamtheit der aktuell eingesetzten Techniken zum Auffinden, Darstellen, Übertragen und Präsentieren beliebiger Daten, so wird offenbar, daß der Autor _ immerhin Direktor des World Wide Web Konsortiums und „Erfinder“ des größten Teils der gegenwärtig eingesetzten Techniken wie URL, HTTP und HTML _, diesen eine Verfehlung des Ziels einer zumindest gut zu nennenden Zusammenarbeit von Mensch und Maschine zuschreibt.
Im wesentlichen speist sich die formulierte Kritik aus dem bisher mit automatisierten technischen Mitteln nicht vollziehbaren Übergang der durch das weltweite Netz angebotenen Daten zu Informationen im Shannon'schen Sinne. Diese Interpretation bleibt für alle aus dem Web gewonnenen Daten dem kognitiven Prozeß des Empfängers überlassen.

Dasselbe gilt umgekehrt für die von einem menschlichen Nutzer zu Daten reduzierten Informationen, die an das Netz -- etwa an Suchmaschinen -- übermittelt werden. Das vorherrschende Codierungsformat für Daten beider Transferrichtungen ist hierbei nahezu ausschließlich in einer natürlichen Sprache formulierter Text.

In der Konsequenz dieses Interaktionsparadigmas ergeben sich Nutzungsmuster, die jedem WWW-Anwender vertraut sind:

Die skizzierten mehrfach notwendigen Interpretationsvorgänge kennzeichnen den aktuellen Umgang mit Web-verfügbaren Inhalten und motivieren gleichermaßen die Vision des Semantischen Webs.
Im Spiegel der diskutierten Nutzungsmuster ergibt sich die Zielsetzung der Semantic Web Initiative des World Wide Web Konsortium im Stile der durch Berners-Lee erhobenen Forderung: Techniken zu entwickeln und zu etablieren, welche die Interaktion zwischen menschlichem Nutzer und Computer vereinfachen.

Die apostrophierte Anreicherung der im Web publizierten Daten kann jedoch kaum durch den Konsumenten geschehen, da er im allgemeinen Falle nicht über die notwendigen (Zusatz-)Informationen verfügt um diesen Vorgang durchführen zu können. Daher muß diese Anreicherung bereits vor der Publikation im Web, idealerweise schon zum Erstellungszeitpunkt durch den Verfasser selbst, erfolgen. Dieser ergänzt die erzeugten Daten um zusätzliche beschreibende Anteile, sog. Metadaten.
Metadaten -- im einfachsten Wortsinne also Daten über Daten -- zu XML codierten Inhalten lassen sich prinzipiell in frei wählbaren Formaten verfassen und ablegen. Vielmehr noch, im weitesten Sinne erfüllt jegliche Art eines deskriptiven Datums zu einem gegebenen Datum die eingeführte Sinngebung.

Wesentlich für die Vision des Semantic Web ist jedoch nicht die Metadatenexistenz an sich, sondern der Wunsch nach Maschinenverarbeitbarkeit zur Unterstützung der Benutzerinteraktion mit den durch die Metadaten beschriebenen Daten.

Aus diesem Wunsche heraus wird die enge Verbindung des Technikgebietes XML mit der Idee des Semantic Web offenbar. Eignet sich doch die selbst als Metasprache angelegte XML in besonderer Weise zur Formalisierung der für das Sematic Web existenznotwendigen Metainformation; wenngleich diese Formalisierung selbst nur auf der deskriptiven Metaebene der syntaktischen Beschreibung anzusiedlen ist, wie einschränkend angemerkt sei. Vielmehr noch, verschiebt dieser -- an sich naheliegende und valide -- Formalisierungsansatz die notwendige Semantische Vereinheitlichung zu Gunsten der durch die XML erfolgten Syntaktischen auf die Meta-Metaebene. Durch die Selbstbeschreibungsfähigkeit der XML kollidiert jedoch auf dieser Ebene der Semantikbegriff XML Schemas mit der dort zu etablierenden Semantikbeschreibung der durch das Schema definierten Sprache. Gänzlich unlösbar wird das Ansiedelungsproblem durch die Organisation des XML-Schemastandards als wiederum selbstbeschreibende Sprache, die den XML-Schemastandard selbst zu seiner syntaktischen und semantischen Beschreibung heranzieht ...

Zu dieser syntaktisch induzierten Semantikansiedelungsproblematik tritt eine semantisch induzierte Syntaxansiedelungsproblematik bei der strukturellen Definition der deskriptiven Metainformation selbst. Konkret stellt sich die Frage der zu wählenden Abstraktionsebene bei der Sprachformulierung einer allgemein einsetzbaren Metasprache zur Codierung beschreibender Daten zu XML codierten Daten.

Wird der Abstraktionsgrad zu hoch gewählt, so geht dies zwar mit einer prinzipiellen Verbreiterung des Einsatzgebietes, d.h. einer größeren Menge beschreibbarer Entitäten einher, schränkt jedoch in gleicher Weise die Spezifität der so formulierbaren Aussagen ein.

Wird der Abstraktionsgrad hingegen möglichst niedrig gewählt, so gewinnt man zwar einerseits ausdetaillierte Entitätsbeschreibungen, diese jedoch nur für sehr wenige Entitäten.

Vor dem Hintergrund dieser Problematik finden im Kontext des Semantic Web zwei Ansätze Verwendung, die in ihrer Kombination den Zielsetzungen beider konkurrierender Ansprüche zu genügen suchen.
So definiert das Resource Description Framework (RDF) ein Vokabular zur Darstellung beliebiger Aussage über Ressourcen. Zur Beschreibung von Syntax kann für RDF XML Schema Anwendung finden.
Zur Sematikdefinition greift RDF jedoch nicht auf XML-Schema zurück, sondern die eigens zum Zwecke der RDF-Beschreibung entwickelte Metasprache RDF Schema welche wiederum selbstbeschreibend organisiert ist. Dieser Schritt fundiert die RDF zugedachte Rolle eines formalisierten Metadatendefinitionsvokabulars gegenüber XML Schema, dessen Einsatzzweck in der syntaktischen Beschreibung beliebiger Vokabulare und der Semantikdefinition der XML-Schemasprache erschöpft ist.

RDF selbst bietet eine einfache XML-Syntax zur Formulierung von Aussagen über Ressourcen an. Der Begriff der Ressource ist dabei eng an den der eineindeutigen Identifizierbarkeit gekoppelt. Diese wird hierzu mit der Technik der Universal Resource Identification synonymisiert. Inhaltlich orientieren sich die mittels RDF formulierbaren Aussagen an der Satzstruktur der englischen Sprache und gestatten Zuordnungen von prädikativ angebundenen Werten (Objekt) zu Ressourcen (Subjekt).

Abbildung 42 zeigt die typische graphische Visualisierung einer RDF-Information. Die Aussage „Mario Jeckle ist der Autor der Ressource http://www.jeckle.de/vorlesung/xml/script.html“ wird durch zwei mittels einer annotierten gerichteten Kante verbundene Knoten dargestellt.
Im Beispiel wird durch RDF eine Aussage über die die als Ellipse dargestellte Ressource http://www.jeckle.de/vorlesung/xml/script.html formuliert. Über diese Ressource wird eine durch das Prädikat, es ist als Beschriftung (Autor) auf der Pfeil dargestellt, formulierte Aussage getroffen. Das Prädikat ist daher das bestimmende Element der Beziehung zwischen Ressource und Objekt, welches als benanntes Rechteck (Mario Jeckle) dargestellt wird.
Aus dem Tripel Ressource--Property--Literal (Subjekt--Prädikat--Objekt) erschließt sich der Sinn der Gesamtaussage als „Die durch http://www.jeckle.de/vorlesung/xml/script.html eineindeutig identifizierte Ressource besitzt einen Autor der Mario Jeckle genannt wird“.

RDF-Beschreibungsdiagram

Komplementär zur graphischen Notation definiert die RDF-Spezifikation ein XML-Vokabular zur textuellen Repräsentation der beschreibenden Metadaten einer Ressource.
Es definiert im Namensraum http://www.w3.org/1999/02/22-rdf-syntax-ns# u.a. die Basielemente RDF, Description, type sowie deren Attribute.

Unter Verwendung des XML-Vokabulars für RDF kann die in Abbildung 42 graphisch formulierte Aussage auch codiert werden als:

Beispiel 26: XML/RDF-Darstellung
Beispiel 94: XML/RDF-Darstellung
(1)<?xml version="1.0"?>
(2)<rdf:RDF 
(3)	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
(4)	xmlns:myNS="http://www.jeckle.de">
(5)	<rdf:Description rdf:about="http://www.jeckle.de/vorlesung/xml/script.html">
(6)		<myNS:Autor>Mario Jeckle</myNS:Autor>
(7)	</rdf:Description>
(8)</rdf:RDF>
Download des Beispiels


Hierbei folgt die Umsetzung des Graphen in die XML-Syntax folgendem Schema:

<RDF 
xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:myNS="eigener Namensraum">
<Description rdf:about="Ressource/Subjekt">
<myNS:Eigenschaft/Prädikat>Objekt/Literal</myNS:Eigenschaft/Prädikat>
</Description>
</RDF>

Im Beispiel wird daher das durch den RDF-Anwender definierte Element Autor verwendet, welches das Prädikat ausdrückt. Dieses Element ist nicht durch das standardisierte RDF-Vokabular vorgegeben, sondern kann durch den Ersteller des RDF-Tripels frei in seiner Syntax und Semantik festgelegt werden. Aus diesem Grunde ist das Element Autor auch nicht dem RDF-Standardnamensraum zugeordnet, sondern einem anwenderdefinierten.

Oftmals besteht der Wunsch mehr als eine Aussage über eine Ressource zu treffen. Dieser Fall kann sowohl in Ausprägung aufteten, daß verschiedene Prädikate diese verschiedenen Aussagen identifizieren, als auch, daß das Prädikat mehrteilig ist, d.h. mehr als ein Einzelobjekt durch das Prädikat angebunden wird.
Der erste Fall läßt sich durch Definition mehrerer separater aus den Prädikaten resultierender Elemente im Rumpf des Description-Elements realisieren, was Beispiel 95 an der Aussage „Mario Jeckle ist der Autor der Ressource http://www.jeckle.de/vorlesung/xml/script.html und besitzt die Mailadresse mario@jeckle.de“ zeigt.

Beispiel 27: XML/RDF-Darstellung mit mehreren Prädikaten
Beispiel 95: XML/RDF-Darstellung mit mehreren Prädikaten
(1)<?xml version="1.0"?>
(2)<rdf:RDF 
(3)	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
(4)	xmlns:myNS1="http://www.jeckle.de"
(5)	xmlns:myNS2="http://www.example.com">
(6)	<rdf:Description rdf:about="http://www.jeckle.de/vorlesung/xml/script.html">
(7)		<myNS1:Autor>Mario Jeckle</myNS1:Autor>
(8)		<myNS2:Mail>mario@jeckle.de</myNS2:Mail>
(9)	</rdf:Description>
(10)</rdf:RDF>
Download des Beispiels


Für den Fall, daß dasselbe Prädikat mehrere Objekte referenziert verlangt RDF die Einführung eines „Stellvertreterobjektes“ welches die Verweise auf die angebundenen Objekte kapselt.
Abbildung 43 stellt diesen Sachverhalt graphisch dar und Beispiel 96 zeigt die korrekte XML-Serialisierung.

RDF-Tripel der ein mehrteiliges Prädikat beinhaltet
Beispiel 28: XML/RDF-Darstellung eines mehrteiligen Prädikats
Beispiel 96: XML/RDF-Darstellung eines mehrteiligen Prädikats
(1)<rdf:RDF
(2)	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
(3)	xmlns:s="http://www.example.com"
(4)	xmlns:t="http://www.examples.org">
(5)  <rdf:Description rdf:about="http://www.jeckle.de">
(6)    <s:Autor rdf:resource="http://www.jeckle.de/person/0815"/>
(7)  </rdf:Description>
(8)
(9)  <rdf:Description rdf:about="http://www.jeckle.de/person/0815">
(10)    <t:Name>Mario Jeckle</t:Name>
(11)    <t:Email>mario@jeckle.de</t:Email>
(12)  </rdf:Description>
(13)</rdf:RDF>
Download des Beispiels


Anwendung des Resource Description Frameworks

RDF-basierte Beschreibungen finden heute vielfältige Anwendung zur standardisierten Ablage von strukturierten Metadaten. Insbesondere im Hypertextumfeld stellt RDF unter Nutzung des Metadatenvokabulars Dublin Core einen interessanten und vielversprechenden Ansatz dar.
Hierbei werden die RDF-codierten XML-Daten allerdings nicht direkt in das XHTML-Dokument eingefügt, da verfügbare Browser diese bei der Erzeugung der Präsentationsansicht nicht ignorieren und daher die RDF-Inhalte im Klartext auslesen, sondern durch das XHTML link-Element extern referenziert.

Auf der Basis des RDF-Standards ist es somit möglich, in ihrem Detaillierungsgrad frei variierende deskriptive Daten zu einer beliebigen Web Ressource so abzulegen, daß sie auf der Basis von XML maschinell weiterverarbeitet werden können. Syntax und Struktursemantik werden hierbei durch die W3C-Empfehlungsdokumente spezifiziert. Ungeklärt ist bisher lediglich noch die semantische Charakterisierung der deskriptiven Dateninhalte selbst. Durch die Etablierung des Resource Description Frameworks wird zwar ein wesentlicher Schritt hin zu einer semantikbasierten Interoperabilität unternommen, jedoch kann wirkliche Semantik auch durch RDF nicht ausgedrückt werden. Im Grunde handelt es sich bei RDF um einen sehr flexibel einsetzbaren und leistungsfähigen Mechanismus zur freien Ressourcennotation, welcher letztlich die deskriptiven Daten auf eine textuelle Repräsentation in einer natürlichen Sprache zurückführt.

Web-Referenzen 4: Weiterführende Links
Web-Referenzen 16: Weiterführende Links


back to top   3  Anwendungen der XML im praktischen Einsatz ...

 

Im nachfolgenden Kapitel sind die Grundlagen der Anwendung des Technikgebietes XML in Applikationen und Architekturen betrachtet.
Hierzu werden zunächst die gängigen Schnittstellen zum Zugriff auf XML-strukturierte Daten aus Hochsprachenapplikationen betrachtet. Neben der Simple API for XML, einem einfach zu implementierenden Mechanismus, wird mit dem Document Object Model des World Wide Web Konsortiums eine direkte Abbildung von XML-Dokumenten in Hauptspeicherstrukturen eingeführt. Dieses Modell hat in der Vergangenheit als Datenstruktur in Web-Browsern und weiteren XML-verarbeitenden Softwarelösungen einige Bedeutung erlangt.
Mit SUNs Vorschlag einer Anbindung von XML-Schema-beschriebenen Datenstrukturen und Applikationsobjekten der Programmiersprache Java wird ein neuer Ansatz zur engen Kopplung zwischen Hochsprache und XML-Serialisierungsformat der Laufzeitobjekte vorgestellt.
Den Abschluß des Kapitels bildet die Diskussion einiger Grundlagen zur persistenten Speicherung von XML-Dokumenten in Datenbanksystemen, sowie die Vorstellung der SOAP-Spezifikation, welche den Transport entfernter Methodenaufrufe mittels XML einführt.

3.1   Die Simple API for XML

Die Simple API for XML (abgekürzt zu: SAX) entstand aus einer durch David Megginson initiierten Aktivität der XML-Mailingliste xml-dev. Sie stellt einen einfachen leichtgewichtigen Mechanismus für die Ereignis-basierte Verarbeitung von XML-Dokumenten dar. Die Charakterisierung als leichtgewichtiger Ansatz bezieht sich sowohl auf den Implementierungsaufwand der API selbst, als auch ihren Integrationsaufwand in eigene Applikationen.
Ursprünglich entstand die SAX-API aus einer Sammlung generischer Java-Schnittstellen für XML-Parser. Inzwischen hat sie sich jedoch als eigenständige Möglichkeit zur Verarbeitung von XML-Dokumenten in verschiedenen Hochsprachen entwickelt. So existieren neben den Umsetzungen für Java auch Implementierungen für C++, Python, Perl und Eiffel. Im folgenden wird aus Gründen der weitesten Verbreitung die Java-Umsetzung der SAX2-Schnittstelle behandelt.
SAX2 treibt den Vorgängeransatz hinsichtlich der jüngeren Entwicklungen im XML-Umfeld (wie Namensräume) voran, behält jedoch die Grundidee bei.
Die nachfolgenden Beispiele beziehen sich auf die SAX2-Implementierung, die durch SUN für Java unter dem Namen Java APIs for XML Processing (JAXP) veröffentlicht wurde und seit Version 1.4 Bestandteil des JDK ist.

Struktur der SAX-API

SAX-Implementierungen weisen üblicherweise drei erkennbare Blöcke auf:

Das SAX-Ausführungsmodell

Jeder SAX-basierte Parser arbeitet nach demselben Ausführungsmodell. Es definiert eine Reihe von Ereignissen, die durch Operationen (sog. Call-Backs) behandelt werden. Der Aufruf der Operationen zum Zeitpunkt des Ereigniseintritts erfolgt immer durch den Parser. Ein expliziter Aufruf durch den Programmierer sollte in jedem Falle unterbleiben!
Der resultierende Programmcode weist daher keinen erkennbaren durchgängigen Kontrollfluß auf, vielmehr ergibt sich dieser durch die serielle Aktivierung der verschiedenen Ereignisbehandlungsroutinen aus dem Eingabedokument.
SAX impliziert jedoch keinerlei Speicherstruktur zur Laufzeit. Als Konsequenz ist sein Ansatz -- mit nur geringen Modifikationen -- auf nahezu beliebige Programmiersprachen übertragbar. Darüberhinaus stellt SAX nur minimale Anforderungen an den verfügbaren Hauptspeicherausbau; der sich nach Art und Umfang der Übergabeparameter einer call-back-Operation richtet. Diese Art der ereignisgetriebenen Verarbeitung eines XML-Dokuments eignet sich daher in besonderer Weise für Geräte mit geringem Hauptspeicherausbau, bzw. generell zur Verarbeitung von XML-Dokumenten die den verfügbaren oder adressierbaren Hauptspeicher übersteigen.
Da sich eine SAX-Applikation immer passiv verhält und auf Fremdaktivierung -- durch Auswerfen der entsprechenden Ereignisse -- wartet, wird dieses Ausführungsmodell auch als Push Model charakterisiert.
Aus der Anlage der SAX-Verarbeitung folgt direkt, daß es keinerlei Modifikationen am Eingangsdokument erlaubt. Lediglich durch veränderte Ausgabe des Eingabedokuments lassen sich einfache Transformationen realisieren.

Der Code des Beispiels 97 zeigt eine Implementierung der vordefinierten call-back Funktionen startDocument und endDocument, die durch den Parser zu Lese-Beginn der XML-Eingabe und nach Abschluß des Lesevorganges aufgerufen werden.
Die Signatur der beiden Operationen wird durch die Klasse DefaultHandler (definiert im Paket org.xml.sax.helpers) vorgegeben. Deshalb erbt die Beispielklasse (SAXExample1) von dieser Klasse.
Bei SAX handelt es sich um eine passive Schnittstelle, die des Aufrufs durch den lesenden Parser bedarf. Hierzu wird zunächst durch den Aufruf SAXParserFactory.newInstance() ein Objekt des Typs SAXParserFactory erzeugt. Instanzen dieser Klasse stellen verschiedene konfigurierbare SAX-Parser Implementierungen zur Verfügung. Unter Nutzung der aktuellen Konfiguration wird mittels newSAXParser ein neuer Parser erzeugt. Im Beispiel wird die Vorgabekonfiguration verwendet.
Die Methode parse des Parser-Objekts führt auf dem über Kommandozeilenparameter (args[0]) übergebenen Dokument den Lesevorgang durch. Der zweite Aufrufparameter der Methode bezeichnet dasjenige Objekt, welches Implementierungen der in DefaultHandler definierten Operationen anbietet. Im Beispiel ist dies die Klasse SAXExample1 selbst.

Nach der Übersetzung durch javac SAXExample1.java kann die Anwendung mit beliebigen XML-Dokumenten zur Ausführung gebracht werden.
Für das Beispiel der Projektverwaltung liefert der Aufruf java SAXExample1 projektverwaltung5.xml folgende Ausgabe:
document started
document ended

Beispiel 1: Ein einfache SAX-basierte Applikation
Beispiel 97: Ein einfache SAX-basierte Applikation
(1)import org.xml.sax.helpers.DefaultHandler;
(2)import javax.xml.parsers.SAXParser;
(3)import javax.xml.parsers.SAXParserFactory;
(4)
(5)public class SAXExample1 extends DefaultHandler {
(6)    public void startDocument() {
(7)        System.out.println("document started");
(8)    } //startDocument()
(9)
(10)    public void endDocument() {
(11)        System.out.println("document ended");
(12)    } //endDocument()
(13)
(14)
(15)    public static void main(String args[]) throws Exception {
(16)        SAXParserFactory spf = SAXParserFactory.newInstance();
(17)
(18)        SAXParser sp = spf.newSAXParser();
(19)        sp.parse(args[0], new SAXExample1());
(20)    } //main()
(21)}//class SAXExample1
Download des Beispiels


Die SAX2-Schnittstellen

Die grundlegende Schnittstelle der SAX2-API wird mit ContentHandler bezeichnet, sie versammelt Operationen zur Abbildung des logischen Inhaltes eines XML-Dokumentes. Die im Beispiel 97 verwendete Basisklasse DefaultHandler implementiert u.a. diese Schnittstelle und stellt sie so der Beispielapplikation zur Verfügung.
Die Übersicht der Tabelle 25 stellt die einzelnen Operationen der Schnittstelle mit ihrer Signatur und Funktionalität zusammen.

Tabelle  25: Die Schnittstelle ContentHandler
Tabelle 25: Die Schnittstelle ContentHandler
Operation
Funktionalität
Aufruf zu Beginn eines Dokuments.
Naturgemäß wird diese Methode nur einmal ausgeführt.
Liefert die deklarierten Verarbeitungsanweisungen.
Diese können vor und nach Eintritt des startDocument-Ereignisses auftreten.
Spezifikationgemäß wird der XML-Prolog nicht als Processing Instruction behandelt und daher auch kein Ereignis dieses Typs ausgelöst.
Aufruf zu Beginn (öffnender Tag) eines Elements.
Neben dem Elementnamen (ohne Namensraumpräfix: localName, oder als qualifizierter Name in qName)
Anmerkung: Namensrauminformationen werden nur erzeugt, wenn der Parser entsprechend konfiguriert wurde.
Objekte des Type Attributes enthalten die Attribute eines Elements in der Reihenfolge ihrer Definition. Zu jedem Attribut sind neben dem lokalen und dem qualifizierten Namen die Namensraum URI sowie Inhalt und Typ gemäß XML v1.0 abrufbar.
Aufruf bei der Verarbeitung von Zeichenkettendaten innerhalb eines Elements.
ch enthält ab der Position start Zeichenketten-artige Daten der Länge length.
Aufruf bei Erreichen eines Elementendes.
Die Übergabeparameter entsprechen denen des zugehörigen startElement-Aufrufs.
Anmerkung: Auch für leere Elemente wird das Ergeignispaar aus startElement und endElement erzeugt.
Signalisiert den Beginn des Gültigkeitsbereits des Namensraumkürzels prefix. uri enthält die vollständige URI des gebundenen Namensraums.
Ist prefix leer, so handelt es sich um die Redefinition des Vorgabenamensraums.
Das Ereignis wird vor dem ersten Element des Namensraums (d.h. dem Element, das die Präfixbindung enthält oder den Vorgabenamensraum überschreibt) ausgelöst.
Signalisiert das Ende des Gültigkeitsbereichs eines Namensraums.
Ist der Übergabeparameter leer, so bezieht sich das Ereignis auf den Vorgabenamensraum.
Das Ereignis tritt nach dem endElement-Ereignis des letzten Elements im Namensraum ein.
Wird als letztes Ereignis des Parsingvorganges ausgelöst.


Der Code aus Beispiel 98 zeigt die Nutzung der verschiedenen Ereignisse zur Erzeugung einer kleinen Dokumentstatistik.
Gegenüber dem vorhergehenden Beispiel wird hier zusätzlich die Schnittstelle Attributes aus dem Paket org.xml.sax importiert.
Nach Abschluß des vollständigen Lesevorganges, d.h. Eintritt des Ereignisses endDocument, werden die aufsummierten Zahlen durch die Methode printStatistics auf der Standardausgabe dargestellt.

Beispiel 2: SAX2-Ereignisse
Beispiel 98: SAX2-Ereignisse
(1)import org.xml.sax.Attributes;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)
(6)public class SAXExample2 extends DefaultHandler {
(7)    private int startDocument = 0,
(8)    endDocument = 0,
(9)    characters = 0,
(10)    startElement = 0,
(11)    endElement = 0,
(12)    attributes = 0;
(13)
(14)    public void printStatistics() {
(15)        System.out.println("# startDocument events:" + startDocument + "\n" +
(16)                "# endDocument events:" + endDocument + "\n" +
(17)                "# startElement events:" + startElement + "\n" +
(18)                "# endElement events:" + endElement + "\n" +
(19)                "# character events:" + characters + "\n" +
(20)                "# attributes:" + attributes + "\n"
(21)        );
(22)    } //printStatistics()
(23)
(24)    public void startDocument() {
(25)        System.out.println("Analyzing ...");
(26)        startDocument++;
(27)    } //startDocument()
(28)
(29)    public void endDocument() {
(30)        endDocument++;
(31)        printStatistics();
(32)    } //endDocument()
(33)
(34)    public void characters(char[] ch, int start, int length) {
(35)        characters++;
(36)    } //characters()
(37)
(38)    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
(39)        startElement++;
(40)        attributes += atts.getLength();
(41)    } //startElement()
(42)
(43)    public void endElement(String namespaceURI, String localName, String qName) {
(44)        endElement++;
(45)    } //endElement()
(46)
(47)    public static void main(String args[]) throws Exception {
(48)        SAXParserFactory spf = SAXParserFactory.newInstance();
(49)
(50)        SAXParser sp = spf.newSAXParser();
(51)        sp.parse(args[0], new SAXExample2());
(52)    } //main()
(53)}//class SAXExample2
Download des Beispiels


Das Programm aus Beispiel 99 implementiert eine Häufigkeitsermittlung für Elementnamen.
Hierzu wird mittels der Java-Collection-API-Klasse HashMap eine Liste mit Tupeln aus Elementnamen und Auftretensanzahlen verwaltet. Eintragungen und Aktualisierungen dieser Liste erfolgen bei jedem startElement-Ereignis.

Beispiel 3: Häufigkeitsermittlung einzelner Elementnamen
Beispiel 99: Häufigkeitsermittlung einzelner Elementnamen
(1)import org.xml.sax.Attributes;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)import java.util.HashMap;
(6)
(7)public class SAXExample41 extends DefaultHandler {
(8)    private HashMap elementHM;
(9)    private final Integer ONE = new Integer(1);
(10)
(11)    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
(12)        Integer freq = (Integer) elementHM.get(qName);
(13)
(14)        elementHM.put(qName, (freq == null ? ONE : new Integer(freq.intValue() + 1)));
(15)    } //startElement()
(16)
(17)    public void endDocument() {
(18)        System.out.println(elementHM);
(19)    } //endDocument()
(20)
(21)    public static void main(String args[]) throws Exception {
(22)        SAXParserFactory spf = SAXParserFactory.newInstance();
(23)        SAXParser sp = spf.newSAXParser();
(24)        sp.parse(args[0], new SAXExample41());
(25)    } //main()
(26)
(27)    public SAXExample41() {
(28)        elementHM = new HashMap();
(29)    } //constructor
(30)}//class SAXExample41
Download des Beispiels


Angewendet auf die Projektverwaltung liefert das Programm folgende Ausgabe:
{Qualifikation=3, em=3, Qualifikationsprofil=1, Leistungsstufe=1, ProjektVerwaltung=1, Person=3, Projekt=2, b=1, u=3, Nachname=3, Vorname=4}

Angewendet auf das Dokument aus Beispiel 20 liefert der Code jedoch die Ausgabe: {document=1, svg=1, ci=3, math=1, g=1, text=1, set=2}!
Offensichtlich ignoriert der verwendete SAX-Parser in der Standardkonfiguration die deklarierten Namensräume.

Zur Änderung dieses Verhaltens, in eine XML v1.0 2nd editon konforme Variante, kann die SAXParserFactory entsprechend instruiert werden.
Für die SUN-Implementierung geschieht dies durch die Methode setNamespaceAware.
Beispiel 100 modifiziert den bisherigen Code entsprechend. Zusätzlich wird die Routine zur Zählung der Elementauftritte entsprechend angepaßt.

Beispiel 4: Namensraum-konformer SAX-Parser
Beispiel 100: Namensraum-konformer SAX-Parser
(1)import org.xml.sax.Attributes;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)import java.util.HashMap;
(6)
(7)public class SAXExample4 extends DefaultHandler {
(8)    private static HashMap elementHM;
(9)    private static final Integer ONE = new Integer(1);
(10)
(11)    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
(12)        String elementFullName = new String(namespaceURI + ":" + localName);
(13)
(14)        Integer freq = (Integer) elementHM.get(elementFullName);
(15)
(16)        elementHM.put(elementFullName, (freq == null ? ONE : new Integer(freq.intValue() + 1)));
(17)    } //startElement()
(18)
(19)    public void endDocument() {
(20)        System.out.println(elementHM);
(21)    } //endDocument()
(22)
(23)
(24)    public static void main(String args[]) throws Exception {
(25)        elementHM = new HashMap();
(26)
(27)        SAXParserFactory spf = SAXParserFactory.newInstance();
(28)
(29)        spf.setNamespaceAware(true);
(30)
(31)        SAXParser sp = spf.newSAXParser();
(32)
(33)        sp.parse(args[0], new SAXExample4());
(34)    } //main(args[])
(35)}//class SAXExample4
Download des Beispiels


Angewendet auf das Beispiel-Dokument liefert es nun das erwartete korrekte Ergebnis:
{http://www.w3.org/1998/Math/MathML:set=1,
http://www.w3.org/1998/Math/MathML:math=1,
http://www.w3.org/2000/svg:svg=1,
http://www.w3.org/1998/Math/MathML:ci=3,
http://www.w3.org/2000/svg:text=1,
:document=1,
http://www.w3.org/2000/svg:g=1,
http://www.w3.org/2000/svg:set=1}

Konsequenterweise wird dem Wurzelelement document, für das kein Namensraum definiert ist (es befindet sich daher spezifikationsgemäß im NULL-Namensraum), die leere Namensraum-URI vorangestellt.
Hinweis: Bei der Ausgabenotation handelt es sich um keine syntaktisch korrekte Elementdeklaration, sie dient lediglich der Veranschaulichung!

Über die gezeigte parserspezifische Möglichkeit zur Aktivierung der namensraumkonformen Verarbeitung hinaus setzen alle SAX-Implementierungen die Methode setFeature für die ParserFactory um.
Sie gestattet es durch standardisierte Namen (tatsächlich werden URIs verwendet) gewisse Eigenschaften an- und abzuschalten.
Die Funktionalität des Beispiels 100 ließe sich daher auch mit folgendem Code erreichen:

Beispiel 5: Namensraum-konformer SAX-Parser (nutzt SAX-Features)
Beispiel 101: Namensraum-konformer SAX-Parser (nutzt SAX-Features)
(1)import org.xml.sax.Attributes;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)import java.util.HashMap;
(6)
(7)public class SAXExample42 extends DefaultHandler {
(8)    private HashMap elementHM;
(9)    private final Integer ONE = new Integer(1);
(10)
(11)    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
(12)        String elementFullName = new String(namespaceURI + ":" + localName);
(13)
(14)        Integer freq = (Integer) elementHM.get(elementFullName);
(15)
(16)        elementHM.put(elementFullName, (freq == null ? ONE : new Integer(freq.intValue() + 1)));
(17)    } //startElement()
(18)
(19)    public void endDocument() {
(20)        System.out.println(elementHM);
(21)    } //endDocument()
(22)
(23)
(24)    public static void main(String args[]) throws Exception {
(25)        SAXParserFactory spf = SAXParserFactory.newInstance();
(26)        spf.setFeature("http://xml.org/sax/features/namespaces", true);
(27)
(28)
(29)        SAXParser sp = spf.newSAXParser();
(30)
(31)        sp.parse(args[0], new SAXExample42());
(32)    } //main(args[])
(33)    public SAXExample42() {
(34)        elementHM = new HashMap();
(35)    } //constructor
(36)}//class SAXExample42
Download des Beispiels


Das Beispiel ersetzt den Aufruf von setNamespaceAware durch die Aktivierung der beiden Features http://xml.org/sax/features/namespaces und http://xml.org/sax/features/namespace-prefixes um dieselbe Funktionalität zu erreichen.

Einschließlich dieser Eigenschaften definiert die SAX2-Schnittstelle folgende Features:

Tabelle  26: SAX2-Features
Tabelle 26: SAX2-Features
Feature-URI
Funktionalität
http://xml.org/sax/features/namespace
Steuert die Berücksichtung von Namensräumen
http://xml.org/sax/features/namespace-prefixes
Steuert ob die Namensraumdeklarations(pseudo-)attribute als den Attributen gleichgestellt behandelt werden
http://xml.org/sax/features/string-interning
Steuert den Aufruf der Methode intern zur Zeichenkettenverarbeitung
http://xml.org/sax/features/validation
Aktiviert bzw. Deaktiviert den validierenden Modus.
Wird dieses Feature aktiviert, so müssen auch external-general-entities und external-parameter-entities aktiviert sein.
http://xml.org/sax/features/external-general-entities
Steuert die Inklusion externer Textentitäten
http://xml.org/sax/features/external-parameter-entities
Steuert die Inklusion externer Parameterentitäten sowie die Verarbeitung einer externen DTD


Fehlerbehandlung

Während der Arbeit mit der SAX-Schnittstelle können innerhalb zwei getrennter Operationsphasen Fehlersituationen auftreten. Zum einen während der Konstruktionsphase des SAX-basierten Parsers, d.h. vor Aufruf der Methode parse, zum anderen während des eigentlichen Parsingvorganges beim Einlesen des Dokuments.
Die Schnittstelle bietet die drei von SAXException abgeleiteten Ausnahmeereignisklassen an: SAXNotRecognizedException, SAXParseException und SAXNotSupportedException.

Fehler während der Parserkonstruktions- und Initialisierungsperiode rühren, abgesehen von externen Effekten, zumeist vom Versuch her, einen Parser in unzulässiger Weise zu parametrisieren.
Das Codebeispiel 102 zeigt dies anhand des Versuchs, eine (nicht existierende) durch die URL http://www.jeckle.de identifizierte Eigenschaft (engl. Property) des Parsers zu setzen. Während der Ausführung tritt konsequenterweise eine SAXNotRecognizedException auf.

Beispiel 6: Auftreten einer SAX-Exception
Beispiel 102: Auftreten einer SAX-Exception
(1)import org.xml.sax.SAXException;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)
(6)
(7)public class SAXExample5 extends DefaultHandler {
(8)    public static void main(String args[]) throws Exception {
(9)        SAXParserFactory spf = SAXParserFactory.newInstance();
(10)
(11)        SAXParser sp = spf.newSAXParser();
(12)
(13)        try {
(14)            System.out.println(sp.getProperty("http://www.jeckle.de"));
(15)        } //try
(16)        catch (SAXException e) {
(17)            System.out.println("SAXException:" + e);
(18)        } //catch()
(19)        sp.parse(args[0], new SAXExample5());
(20)    } //main()
(21)}//class SAXExample5
Download des Beispiels


Tritt während des Parsingvorganges ein Verstoß hinsichtlich der well-formedness Regeln auf, so wird ein SAXParseException-Ausnahmeereignis erzeugt. Es stellt Methoden zur näheren Lokalisierung der Fehlerstelle im Eingabedokument zur Verfügung.
Die Implementierung des Beispiels 103 setzt dies um: Mittels der Methoden getColumnNumber und getLineNumber lassen sich Spalten- und Zeilennummer des Fehlers ermitteln. getSystemId und getPublicId können zur Ausgabe des System-Identifiers, der bei lokaler Referenzierung identisch zum Dateisystempfad ist, bzw. zur Ausgabe des Public-Identifiers -- falls gesetzt -- herangezogen werden.

Beispiel 7: Behandlung einer SAXParseException
Beispiel 103: Behandlung einer SAXParseException
(1)import org.xml.sax.SAXParseException;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)
(6)public class SAXExample6 extends DefaultHandler {
(7)    public static void main(String args[]) throws Exception {
(8)        SAXParserFactory spf = SAXParserFactory.newInstance();
(9)
(10)        SAXParser sp = spf.newSAXParser();
(11)
(12)        try {
(13)            sp.parse(args[0], new SAXExample6());
(14)        } //try
(15)        catch (SAXParseException spe) {
(16)            System.out.println("A SAXParseException occured ...\n" +
(17)                    "at column " + spe.getColumnNumber() + "\n" +
(18)                    "at line " + spe.getLineNumber() + "\n" +
(19)                    "public identifier of document is: " + spe.getPublicId() + "\n" +
(20)                    "system identifier of document is: " + spe.getSystemId());
(21)        } //catch()
(22)    } //main()
(23)}//class SAXExample6
Download des Beispiels


Das Auftreten einer SAXNotSupportedException wird durch den Versuch ausgelöst, eine zulässige und erkannte Parameterisierung des SAX-Parsers vorzunehmen, die durch diesen nicht unterstützt wird.
Diese Fehlersituation läßt sich daher an keinem statischen Beispiel zeigen, sondern hängt von der konkreten Parser-Implementierung ab.

Angewendet auf das nicht-wohlgeformte Dokument aus Beispiel 10 liefert die Ausführung die Ausgabe:

A SAXParseException occured ...
at column 17
at line 3
public identifier of document is: null
system identifier of document is: http://www.jeckle.de/vorlesung/xml/examples/notWellFormed.xml

Das Abschlußbeispiel  104 zeigt eine vollständige Implementierung der verschiedenen SAX-Ereignisse der ConentHandeler-Schnittstelle.
Als Eingabe diene die Beispieldatei:

(1)<?xml version="1.0"?>
(2)<?myPI this is a test?>
(3)   <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
(4)   <head>
(5)      <title>Testpage</title>
(6)   </head>
(7)   <body>
(8)      <p>This is a <a href="http://www.jeckle.de">link</a>
(9)      <svg:svg width="4cm" height="8cm">
(10)         <svg:ellipse cx="2cm" cy="4cm" rx="2cm" ry="1cm"/>
(11)      </svg:svg>      
(12)      </p>
(13)   </body>
(14)</html>
Beispiel 8: Implementierung verschiedener SAX2-Callback-Methoden
Beispiel 104: Implementierung verschiedener SAX2-Callback-Methoden
(1)import org.xml.sax.helpers.DefaultHandler;
(2)import org.xml.sax.Attributes;
(3)import javax.xml.parsers.SAXParserFactory;
(4)import javax.xml.parsers.SAXParser;
(5)import org.xml.sax.SAXParseException;
(6)
(7)public class SAXExample8 extends DefaultHandler {
(8)	public void startDocument() 	{
(9)		System.out.println("EVENT: startDocument");
(10)	} //startDocument()
(11)
(12)	public void endDocument() 	{
(13)		System.out.println("EVENT: endDocument");
(14)	} //endDocument()
(15)
(16)	public void startPrefixMapping(String prefix, String uri)    {
(17)   	System.out.println("EVENT: startPrefixMapping");
(18)   	System.out.println("prefix="+prefix);
(19)   	System.out.println("namespaceURI="+uri);
(20)   } //startPrefixMapping()
(21)
(22)   public void endPrefixMapping(String prefix)    {
(23)   	System.out.println("EVENT: endPrefixMapping");
(24)   	System.out.println("prefix="+prefix);
(25)   } //endPrefixMapping()
(26)
(27)   public void processingInstruction(String target, String data)    {
(28)   	System.out.println("EVENT: processingInstruction");
(29)   	System.out.println("target="+target);
(30)   	System.out.println("data="+data);
(31)   } //processingInstruction()
(32)
(33)	public void ignorableWhitespace(char[] ch, int start, int length) 	{
(34)		System.out.println("EVENT: ignorableWhitespace");
(35)		for (int i=start; i<start+length; i++)
(36)			System.out.print(ch[i]);
(37)		System.out.print("\n");
(38)	} //ignorableWhietespace()
(39)
(40)	public void startElement(String namespaceURI, String localName, String qName, Attributes atts) 	{
(41)		System.out.println("EVENT: startElement");
(42)		System.out.println("namespaceURI="+namespaceURI);
(43)		System.out.println("localName="+localName);
(44)		System.out.println("qName="+qName);
(45)
(46)		for (int i=0; i<atts.getLength(); i++) 		{
(47)			System.out.println("attribute:");
(48)			System.out.println("localName="+atts.getLocalName(i));
(49)			System.out.println("qName="+atts.getQName(i));
(50)			System.out.println("type="+atts.getType(i));
(51)			System.out.println("namespaceURI="+atts.getURI(i));
(52)			System.out.println("value="+atts.getValue(i));
(53)		} //for
(54)	} //startElement()
(55)
(56)	public void endElement(String namespaceURI, String localName, String qName) 	{
(57)		System.out.println("EVENT: endElement");
(58)		System.out.println("namespaceURI="+namespaceURI);
(59)		System.out.println("localName="+localName);
(60)		System.out.println("qName="+qName);
(61)	} //endElement()
(62)
(63)	public void characters(char[] ch, int start, int length) 	{
(64)		System.out.println("EVENT: characters");
(65)		for (int i=start; i<start+length; i++)
(66)			System.out.print(ch[i]);
(67)		System.out.print("\n");
(68)	} //characters()
(69)
(70)   public static void main (String args[]) throws Exception 	{
(71)		SAXParserFactory spf = SAXParserFactory.newInstance();
(72)      spf.setNamespaceAware(true);
(73)		SAXParser sp = spf.newSAXParser();
(74)
(75)		try 		{
(76)			sp.parse( args[0], new SAXExample8() );
(77)		} catch (SAXParseException spe) {
(78)         System.out.println("A SAXParseException occured ...\n"+
(79)                            "at column "+spe.getColumnNumber()+"\n"+
(80)                            "at line "+spe.getLineNumber()+"\n"+
(81)                            "public identifier of document is: "+spe.getPublicId()+"\n"+
(82)                            "system identifier of document is: "+spe.getSystemId());
(83)      } //catch()
(84)	} //main(args[])
(85)}//class SAXExample8
Download des Beispiels


Die Ausführung liefert eine textuelle Ausgabe, deren Ereignisreihenfolge der der Abbildung 44 entspricht

SAX2-Ereignisse während des Parsingvorganges

Einfache Transformationen

Bedingt durch die sequentielle Aktivierung der verschiedenen Ereignisbehandlungsroutinen lassen sich mit SAX sehr komfortabel einfache Dokumenttransformationen, wie z.B. die Umbenennung von Elementen, realisieren.
Der Code aus Beispiel 105 zeigt die Umbenennung eines Elements von foo nach bar. Alle anderen Elemente, Attribute und Zeichenketten-artigen Elementinhalte werden unverändert kopiert.
Hinweis: Das Beispiel berücksichtigt dabei jedoch weder Namensräume noch Processing Instructions.

Beispiel 9: Umbenennung eines Elements
Beispiel 105: Umbenennung eines Elements
(1)import org.xml.sax.Attributes;
(2)import org.xml.sax.helpers.DefaultHandler;
(3)import javax.xml.parsers.SAXParser;
(4)import javax.xml.parsers.SAXParserFactory;
(5)
(6)public class SAXExample7 extends DefaultHandler {
(7)    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
(8)        if (qName == "foo") {
(9)            System.out.print("<bar");
(10)        } //if
(11)        else
(12)            System.out.print("<" + qName);
(13)
(14)        for (int i = 0; i < atts.getLength(); i++) {
(15)            System.out.print(" " + atts.getQName(i) + "=\"" + atts.getValue(i) + "\"");
(16)        } //for
(17)        System.out.println(">");
(18)    } //startElement()
(19)
(20)    public void endElement(String namespaceURI, String localName, String qName) {
(21)        if (qName == "foo") {
(22)            System.out.println("</bar>");
(23)        } //if
(24)        else
(25)            System.out.println("</" + qName + ">");
(26)    } //endElement()
(27)
(28)    public void characters(char[] ch, int start, int length) {
(29)        for (int i = start; i < start + length; i++)
(30)            System.out.print(ch[i]);
(31)    } //characters()
(32)
(33)    public static void main(String args[]) throws Exception {
(34)        SAXParserFactory spf = SAXParserFactory.newInstance();
(35)
(36)        SAXParser sp = spf.newSAXParser();
(37)
(38)        sp.parse(args[0], new SAXExample7());
(39)    } //main()
(40)}//class SAXExample7
Download des Beispiels


Zur Realisierung komplexer Transformationen, insbesondere solcher, die die Zwischenspeicherung von Dokumentinformationen erfordern sind jedoch Ansätze mit expliziter Abbildung in Hauptspeicherstrukturen wie DOM oder XSLT besser geeignet.

Einbindung von SAX in Applikationsprogramme

Beispiel 106 zeigt die Einbindung eines SAX-Parser in ein Applikationsprogramm. Die Anwendung überführt beliebige XML-Eingabedokumente in eine Java-SWING-konforme Baumdarstellung.

Beispiel 10: Konstruktion einer SWING-basierten Baumansicht mit SAX
Beispiel 106: Konstruktion einer SWING-basierten Baumansicht mit SAX
(1)import org.xml.sax.Attributes;
(2)import org.xml.sax.SAXException;
(3)import org.xml.sax.helpers.DefaultHandler;
(4)import javax.swing.JFrame;
(5)import javax.swing.JScrollPane;
(6)import javax.swing.JTree;
(7)import javax.swing.tree.DefaultMutableTreeNode;
(8)import javax.xml.parsers.FactoryConfigurationError;
(9)import javax.xml.parsers.ParserConfigurationException;
(10)import javax.xml.parsers.SAXParser;
(11)import javax.xml.parsers.SAXParserFactory;
(12)import java.awt.BorderLayout;
(13)import java.awt.HeadlessException;
(14)import java.awt.event.WindowAdapter;
(15)import java.awt.event.WindowEvent;
(16)import java.io.IOException;
(17)
(18)public class TreeViewer extends JFrame {
(19)
(20)    public static void main(String argv[]) {
(21)        JFrame frame = new TreeViewer(argv[0]);
(22)        frame.addWindowListener(new WindowAdapter() {
(23)            public void windowClosing(WindowEvent e) {
(24)                System.exit(0);
(25)            }
(26)        });
(27)        frame.pack();
(28)        frame.setVisible(true);
(29)    } //main()
(30)
(31)    public TreeViewer(String XMLFile) {
(32)        super("SAX-based XML Viewer");
(33)        try {
(34)            DefaultMutableTreeNode root = new DefaultMutableTreeNode("DOCUMENT: " + XMLFile);
(35)            JTree tree = new JTree(root);
(36)            JScrollPane treeView = new JScrollPane(tree);
(37)            getContentPane().add(new JScrollPane(treeView), BorderLayout.CENTER);
(38)
(39)            //add elements to root
(40)            SAXParserFactory spf = SAXParserFactory.newInstance();
(41)            spf.setNamespaceAware(true);
(42)            SAXParser sp = spf.newSAXParser();
(43)            sp.parse(XMLFile, new Consumer(root));
(44)        } catch (HeadlessException e) {
(45)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(46)            e.printStackTrace();
(47)        } catch (FactoryConfigurationError factoryConfigurationError) {
(48)            System.out.println("EXCEPTION CAUGHT: " + factoryConfigurationError.getClass().getName());
(49)            factoryConfigurationError.printStackTrace();
(50)        } catch (ParserConfigurationException e) {
(51)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(52)            e.printStackTrace();
(53)        } catch (SAXException e) {
(54)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(55)            e.printStackTrace();
(56)        } catch (IOException e) {
(57)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(58)            e.printStackTrace();
(59)        }
(60)    }
(61)} //class TreeViewer
(62)
(63)class Consumer extends DefaultHandler {
(64)    private DefaultMutableTreeNode current;
(65)
(66)    public Consumer(DefaultMutableTreeNode root) {
(67)        current = root;
(68)    }
(69)
(70)    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
(71)        for (int i = 0; i < atts.getLength(); i++) {
(72)            current.add(new DefaultMutableTreeNode("ATTRIBUTE: " + atts.getQName(i) + "=" + atts.getValue(i)));
(73)        }
(74)
(75)        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("ELEMENT: " + localName);
(76)        current.add(newNode);
(77)        current = newNode;
(78)    }
(79)
(80)    public void endElement(String namespaceURI, String localName, String qName) {
(81)        current = (DefaultMutableTreeNode) current.getParent();
(82)    }
(83)
(84)    public void processingInstruction(String target, String data) {
(85)        current.add(new DefaultMutableTreeNode("PROCESSING INSTRUCTION: " + target));
(86)    }
(87)
(88)    public void characters(char[] ch, int start, int length) {
(89)        current.add(new DefaultMutableTreeNode("CHARACTERS: " + new String(ch, start, length)));
(90)    }
(91)} //class Consumer
Download des Beispiels


Der Code zeigt die sukzessive Konstruktion der Baumansicht entlang der beim Lesevorgang eintretenden SAX-Ereignisse.
Hervorzuheben ist hierbei die Erzeugung je eines Baumknotens innerhalb der Ereignisbehandlungsroutinen startElement, processingInstruction und characters. All diese Methoden fügen einen neuen Kindknoten zum aktuell bearbeiteten Baumknoten zu. Zusätzlich wird innerhalb der Behandlung des startElement-Ereignisses der neu erzeugte Kindknoten für die weitere Verarbeitung als Aktueller definiert und damit eine zusätzliche Baumstufe eröffnet.
Das rekursive Aufsteigen im Baum findet beim Verlassen eines Elements (Ereignis: endElement) statt.
Abbildung 45 zeigt die durch Verarbeitung des Dokuments aus Beispiel 1 erzeugte Bildschirmansicht.

Bildschirmdarstellung der erzeugten Baumdarstellung

Anmerkung zur Graphik: Die vermeintlich „leeren“ CHARACTER-Elemente entstehen durch die nichtdruckbaren Zeichen wie Zeilenumbrüche und Wagenrückläufe.

Abschlußbemerkungen und Einsatzempfehlungen

SAX offenbart sich als leicht einzusetzende und trotzdem für geeignete Anwendungsfälle sehr mächtige Schnittstelle. Insbesondere ist der serielle Verarbeitungsansatz, der nur geringe Hauptspeicheranforderungen stellt, sehr gut für große XML-Dokumente geeignet. Gleichzeitig skalieren SAX-basierte Anwendungen vergleichsweise gut, da das Eingabedokument nur einmal durchlaufen wird.
Als gravierende Nachteile offenbaren sich jedoch die fehlenden Navigationsmöglichkeiten, die der Applikation die Reihenfolge der Elemente im Dokument als Verarbeitungsreihenfolge aufzwingen.
Festzuhalten bleibt, daß es sich bei SAX lediglich um eine Schnittstelle handelt, auf der Parser realisiert werden können. SAX selbst ist jedoch kein solcher.

Web-Referenzen 1: Weiterführende Links
Web-Referenzen 17: Weiterführende Links


3.2   Das Document Object Model

Die W3C-Spezifikation des Document Object Models (abgekürzt als: DOM) definiert eine Programmiersprachen-unabhängig formulierte Menge abstrakter Schnittstellen zum lesenden und schreibenden Zugriff auf gültige HTML und wohlgeformte XML-Dokumente sowie eine Reihe weiterer Formate.
Derzeit verabschiedet (Status einer W3C-Recommendation) ist das sog. DOM Level 1 und die darauf aufsetzende Spezifikation eines DOM Level 2. Aktuell wird bereits an der als DOM Level 3 bezeichneten Weiterentwicklung gearbeitet. Diese Bemühungen haben jedoch erst den Stand eines working drafts erreicht.
DOM Level 2 erweitert die in Level 1 eingeführten Schnittstellen hinsichtlich der Erfordernisse des aktuellen XML-Standes um Namensräume und bietet einige neue Operationen, die seitens der Anwendergemeinde gefordert wurden. Die bisherigen Operationen existieren aus Kompatibilitätsgründen weiter, die Namespace-berücksichtigenden Pendants sind identisch benannt, jedoch um ein angehängtes NS erweitert.

DOM versteht sich als Application Programming Interface (API) für beliebige XML-Dokumente. Hierzu versammelt es auf Basis einer generischen Speicherrepräsentation für XML eine Menge von Operationen zur Extraktion verschiedenster Informationen aus dem Dokument, sowie zur Modifikation der speicherresidenten Strukturen und späteren (Wieder-)Ausgabe in ein XML-Dokument.

Die Konformität zur DOM-Spezifikation fächert sich in die verschiedenen DOM-Module auf. Wird eines der Module implementiert, so spricht man von DOM 2 module Unterstützung für das jeweilige Modul. Wird das Kernmodul core unterstützt, so ist DOM 2 Unterstützung erreicht.
Die einzelnen DOM-Module sind in Tabelle 27 zusammengestellt.

Tabelle  27: Übersicht der DOM-Module
Tabelle 27: Übersicht der DOM-Module
Modul
Aufgabe/Funktionsumfang
Definiert programmiersprachenunabhängige Schnittstellen für den Zugriff auf, und die Manipulation von, Objekten eines Dokuments.
Definiert den über HTML hinausgehenden Teil von Core.
Schnittstellen zur Realisierung verschiedener Sichten auf dasselbe Dokument.
Dieses Modul ist optional; im Falle einer Implementierung muß auch Core umgesetzt werden.
Schnittstellen zum Zugriff auf Informationen eines Stylesheets.
Dieses Modul ist optional; im Falle einer Implementierung muß auch Core umgesetzt werden.
Schnittstellen zum Zugriff auf Informationen einer CSS-Beschreibung.
Dieses Modul ist optional; im Falle einer Implementierung muß auch Core und Views umgesetzt werden.
Schnittstellen zum Zugriff Informationen einer CSS2-Beschreibung.
Dieses Modul ist optional; im Falle einer Implementierung muß auch CSS umgesetzt werden.
Schnittstellen zur plattform- und sprachunabhängigen Behandlung von Ereignissen.
Implementierungen dieses Moduls müssen auch Core umsetzen.
Umfaßt eine Untermenge von Events, die den HTML-spezifischen Ereignissen aus DOM 0 entspricht.
Implementierungen müssen zusätzlich Events und Views unterstützen.
Umfaßt eine Untermenge von Events, die den HTML-spezifischen Maus-Ereignissen aus DOM 0 entspricht.
Implementierungen müssen zusätzlich die Schnittstellen aus UIEvents unterstützen.
Bietet Schnittstellen zur Benachrichtigung bei Ereignissen, durch welche Struktur oder Inhalt eines Dokuments verändert werden (z.B. Hinzufügen oder Ändern eines Elements oder Attributs).
Implementierungen müssen zusätzlich die Schnittstellen aus Events realisieren.
Schnittstellen zum Zugriff auf Bereiche eines XML-Dokuments, wie sie beispielsweise durch Selektionen mit der Maus am Bildschirm in der visuellen Darstellung gebildet werden können.
Implementierungen müssen zusätzlich die Schnittstellen aus Core realisieren.
Bietet mit den Schnittstellen TreeWalker, NodeIterator und NodeFilter Möglichkeiten zur einfachen Traversierung von Dokumentbäumen an.
Implementierungen müssen zusätzlich die Schnittstellen aus Core realisieren.


Die Unterstützung der einzelnen Module kann durch die Schnittstellenfunktion hasFeature der Schnittstelle DOMImplementation des Moduls Core ermittelt werden.
Die Java-Implementierung aus Beispiel 107 zeigt die Nutzung dieser Operation. DOM definiert zwar die Operationssignatur, gebildet aus dem Modulnamen und dessen Version, legt jedoch keine Klasse zur Implementierung fest. Das Beispiel zeigt die Umsetzung für die DOM-Unterstützung im Java Development Kit v1.4

Beispiel 11: Ermittlung der unterstützten DOM-Module
Beispiel 107: Ermittlung der unterstützten DOM-Module
(1)import org.w3c.dom.DOMImplementation;
(2)import javax.xml.parsers.DocumentBuilder;
(3)import javax.xml.parsers.DocumentBuilderFactory;
(4)
(5)public class domtest {
(6)    public static void main(String argv[]) throws Exception {
(7)        // implementation specific part begins ...
(8)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(9)        DocumentBuilder builder = factory.newDocumentBuilder();
(10)        DOMImplementation implementation = builder.getDOMImplementation();
(11)		  // ... ends
(12)    
(13)        String feature[] = {"Core", "XML", "HTML", "Views", "StyleSheets",
(14)                            "CSS", "CSS2", "Events", "UIEvents", "MouseEvents",
(15)                            "MutationEvents", "HTMLEvents", "Range", "Traversal"};
(16)
(17)        for (int i = 0; i < feature.length; i++) {
(18)            System.out.print(feature[i]);
(19)            if (!implementation.hasFeature(feature[i], "2.0")) {
(20)                System.out.println(" not supported");
(21)            } //if 
(22)            else {
(23)                System.out.println(" supported");
(24)            } //else
(25)        } //for
(26)    } //main()
(27)} //class domtest
Download des Beispiels


Die aktuell verfügbare Umsetzung des JDK v1.4.1 liefert daher die Ausgabe:

(1)Core supported
(2)XML supported
(3)HTML not supported
(4)Views not supported
(5)StyleSheets not supported
(6)CSS not supported
(7)CSS2 not supported
(8)Events supported
(9)UIEvents not supported
(10)MouseEvents not supported
(11)MutationEvents supported
(12)HTMLEvents not supported
(13)Range supported
(14)Traversal supported

Das DOM-Objektmodell

Das in CORBA-IDL formulierte DOM-Objektmodell orientiert sich strukturell stark am XML Information Set. DOM erweitert die dort definierte Baum-artige Struktur um Signatur- und Semantikdefinitionen zur Operation auf den erzeugten Speicherobjekten. Der Begriff Objektmodell wurde daher bewußt in Abgrenzung zum Datenmodell gewählt, da durch DOM neben den Datenstrukturen auch darauf aufbauende gekapselte Funktionalität definiert wird.
Jedoch definiert DOM keine Binärrepräsentation der verarbeiteten Dokumentdaten. DOM-implementierende Applikationen können daher durchaus in ihrer Implementierung variieren, insbesondere ist durch DOM nicht die Herstellung einer binären Interoperabilität beabsichtigt.
Ebenso gibt die DOM-Level-1-Spezifikation keinen Weg zur Erzeugung des Objektmodells aus einem XML-Dokument oder zur Ausgabe des Objektmodells in ein XML-Dokument an. Hierfür haben die einzelnen Hersteller in ihren Implementierungen teilweise abweichende Lösungen entwickelt. Zumeist wird das DOM-Objektmodell sukzessive aus den gelieferten Ereignissen eines SAX-Parsers erzeugt.
Dieses „verborgene“ Implementierungsdetail läßt sich vergleichsweise leicht durch Auffangen der SAXParseException-Ausnahme in einer DOM-basierten Parserumgebung prüfen. Tritt während des Konstruktionsvorganges der DOM-Repräsentation ein SAX-Parserfehler ein, so wird spezifikationsgemäß ein Ausnahmeereignisobjekt dieses Typs generiert.
Durch die Orientierung am InfoSet-Ansatz gleichen sich von verschiedenen DOM-Implementierungen erzeugte Speicherstrukturen immer strukturell. Diese Eigenschaft wird als strukturelle Isomorphie bezeichnet.
DOM Level 1 zerfällt in zwei Teile: dem Paket DOM HTML zur Operation auf HTML strukturierten Dokumenten und DOM Core zur Verarbeitung nativer XML-Dokumente. Im folgenden wird ausschließlich das DOM-Kernpaket der aktuellen Spezifikation Level 2 betrachtet. Die Implementierungsbeispiele orientieren sich an SUNs Umsetzung für JDK v1.4.

Die fundamentalen DOM-Schnittstellen

Node

Die Schnittstelle Node konzentriert alle gemeinsamen Anteile der verschiedenen Knoten eines XML-Baumes. Hierunter fallen: Das Dokument selbst, alle darin enthaltenen Attribute, Elemente, Kommentare und Textelemente sowie weitere durch die InfoSet-Spezifikation definierte Primitive.
Das Diagramm der Abbildung 46 zeigt die Schnittstelle mit den durch sie definierten Konstanten zur Codierung der Knotentypisierung, ihnen entspricht jeweils eine eigene DOM-Schnittstelle, neben einigen grundlegenden Attributen zur vereinfachten Navigation. Die aufgeführten Operationen erlauben einige Veränderungen der Knotenstruktur wie das Einfügen oder Anhängen neuer Knoten in ein bestehendes DOM-Objektmodell. Darüberhinaus das Ersetzen, Löschen und Kopieren existierender Knoten.
Die Schnittstelle Node wird von allen im folgenden diskutierten nach Knotentyp spezialisierten Schnittstellen erweitert.

Die DOM2-Schnittstelle Node

Document

Die Schnittstelle Document versammelt die in der Graphik der Abbildung 47 dargestellten Eigenschaften und Operationen.
Sie bildet als Basis den Einstiegspunkt jeder DOM-Baumstruktur.
Abgesehen vom Datentyp DOMString, der als Zeichenkette mit jeweils 16-Bit zur Codierung der Einzelzeichen definiert ist, sind alle verwendeten Datentypen selbst Schnittstellen die durch DOM definiert werden.

Die DOM2-Schnittstelle Document

Der Code des Beispiels 108 zeigt die Erzeugung einer DOM-basierten Speicherstruktur mit SUNs JDK.
Die Pakete zur Realisierung des Einlesevorganges sind in der Hierarchie javax.xml.parsers organisiert. Analog zur Erzeugungs- und Initialisierungsphase eines SAX-Parsers wird auch für DOM zunächst eine factory-Instanz gebildet, die den Parser (ein Objekt der Klasse DocumentBuilder) liefert.
Die Methode parse erzeugt ein Document-Objekt gemäß der W3C Spezifikation (Level 2). Die entsprechenden Schnittstellendefinitionen sind im Paket org.w3c.dom zusammengefaßt.

Beispiel 12: Ein einfacher DOM-basierter Parser
Beispiel 108: Ein einfacher DOM-basierter Parser
(1)import org.w3c.dom.Document;
(2)import javax.xml.parsers.DocumentBuilder;
(3)import javax.xml.parsers.DocumentBuilderFactory;
(4)
(5)public class DOMExample1 {
(6)    public static void main(String[] args) throws Exception {
(7)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(8)        DocumentBuilder builder = factory.newDocumentBuilder();
(9)        Document document = builder.parse(args[0]);
(10)    } //main()
(11)} //class DOMExample1
Download des Beispiels


Der Zugriff auf das Wurzelelement des verarbeiteten Dokuments wird über das Attribut documentElement bereitgestellt. Es liefert ein Objekt des Typs Element.

Element

Die Schnittstelle Element erweitert Node um ein Element und eine Reihe von Operationen zum Zugriff auf XML-Elemente.
Die Graphik stellt diese als UML-Klassendiagramm dar:

Die DOM2-Schnittstelle Element

Beispiel 109 zeigt den Einsatz der Operation hasAttributes, die auf Existenz von Attributen eines gegebenen Elements testet.
Zusätzlich nutzt das Beispiel zwei Methoden, denen keine DOM2-Operationen entsprechen: getTagName und getDocumentElement. Dies rührt aus der Umsetzung der DOM2-Schnittstellendefinition in Java her. Diese Programmiersprache erlaubt in Schnittstellen keine änderbaren Attribute, sondern lediglich Konstanten. Daher stellt die DOM-Implementierung des JDK für diese Attribute eigene Zugriffsmethoden zur Verfügung.

Beispiel 13: Zugriff auf Elementinformation mit DOM2
Beispiel 109: Zugriff auf Elementinformation mit DOM2
(1)import org.w3c.dom.Document;
(2)import org.w3c.dom.Element;
(3)import javax.xml.parsers.DocumentBuilder;
(4)import javax.xml.parsers.DocumentBuilderFactory;
(5)
(6)public class DOMExample2 {
(7)    public static void main(String[] args) throws Exception {
(8)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(9)        DocumentBuilder builder = factory.newDocumentBuilder();
(10)        Document document = builder.parse(args[0]);
(11)
(12)        Element theRootElement = document.getDocumentElement();
(13)
(14)        System.out.println("root element's name: " + theRootElement.getTagName());
(15)
(16)        System.out.print("the element has");
(17)        if (!theRootElement.hasAttributes())
(18)            System.out.print(" no");
(19)        System.out.println(" attributes");
(20)    } //main()
(21)} //class DOMExample2
Download des Beispiels


Angewandt auf die XML-Datei der Projektverwaltung liefert das Programm die Ausgabe:

 root element's name: ProjektVerwaltung the element has attributes

Darüberhinaus gestattet DOM -- im Gegensatz zu SAX -- Modifikationen am eingelesenen Dokument. So wird im nachfolgenden Beispiel dem Wurzelelement des Dokuments (das Objekt theRootElement des Typs Element) ein Attribut (benannt mit myFirstNewAttribute) hinzugefügt und mit dem Wert 01 belegt.
Anschließend wird durch den Aufruf createElement auf dem Dokumentobjekt ein neues Element erzeugt, das jedoch noch nicht im Dokumentbaum plaziert wird. Dies geschieht durch die Methode appendChild.
Der Aufruf der Methode String.println serialisiert den DOM-Baum in eine Zeichenkettenrepräsentation und gibt diese über die Standardausgabe aus.

Beispiel 14: Modifikationen am Dokument mittels DOM2
Beispiel 110: Modifikationen am Dokument mittels DOM2
(1)import org.w3c.dom.Document;
(2)import org.w3c.dom.Element;
(3)import javax.xml.parsers.DocumentBuilder;
(4)import javax.xml.parsers.DocumentBuilderFactory;
(5)
(6)public class DOMExample3 {
(7)    public static void main(String[] args) throws Exception {
(8)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(9)        DocumentBuilder builder = factory.newDocumentBuilder();
(10)        Document document = builder.parse(args[0]);
(11)
(12)        Element theRootElement = document.getDocumentElement();
(13)
(14)        theRootElement.setAttribute("myFirstNewAttribute", "01");
(15)
(16)        Element aNewElement = document.createElement("myNewElement");
(17)
(18)        theRootElement.appendChild(aNewElement);
(19)
(20)        System.out.print(theRootElement);
(21)    } //main()
(22)} //class DOMExample3
Download des Beispiels


Wird das Programm auf einem XML-Dokument ausgeführt, das ausschließlich aus dem Element empty besteht, liefert es die Ausgabe:

<empty myFirstNewAttribute="01"><myNewElement /></empty>

NodeList

Die Schnittstelle NodeList definiert einen Container zur Aufnahme beliebiger Objekte des Typs Node. Sie definiert das Attribut length, welches zu jedem Zeitpunkt die Anzahl der verwalteten Elemente enthält. Der Zugriff auf die verwalteten Nodes erfolgt indexsequentiell durch die Methode item.

Die DOM2-Schnittstelle NodeList

Das Codebeispiel 111 zeigt die Verwendung der Schnittstelle zur Ermittlung der Auftrittsanzahl eines als Kommandozeilenparameter übergebenen Elementnamens.
Die Methode getElementsByTagName der Schnittstelle Document fügt während der Ausführung alle Auftreten von Elementen mit dem gesuchten Namen in die Resultatmenge ein, unbeachtlich deren Position im Dokument.

Beispiel 15: Nutzung der Schnittstelle NodeList
Beispiel 111: Nutzung der Schnittstelle NodeList
(1)import org.w3c.dom.Document;
(2)import org.w3c.dom.Element;
(3)import org.w3c.dom.NodeList;
(4)import javax.xml.parsers.DocumentBuilder;
(5)import javax.xml.parsers.DocumentBuilderFactory;
(6)
(7)public class DOMExample4 {
(8)    public static void main(String[] args) throws Exception {
(9)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(10)        DocumentBuilder builder = factory.newDocumentBuilder();
(11)        Document document = builder.parse(args[0]);
(12)
(13)        Element theRootElement = document.getDocumentElement();
(14)
(15)        NodeList nodes = theRootElement.getElementsByTagName(args[1]);
(16)
(17)        System.out.println("document contains " + nodes.getLength() + " elements of type " + args[1]);
(18)    } //main()
(19)} //class DOMExample4
Download des Beispiels


Attr

Die Schnittstelle Attr erweitert Node um drei Attribute zur Abbildung der Charakteristika eines XML-Attributs.
Die Graphik stellt diese als UML-Klassendiagramm dar:

Die DOM2-Schnittstelle Attr

Die Attribut-spezifischen Eigenschaften werden durch den Attributnamen (name) und seinen Wert (value) abgebildet. Ferner ist verfügbar, ob es sich um ein im eingelesenen Quelldokument auftretendes Attribut handelt, oder durch den Parser der in der DTD oder dem Schema festgelegte Vorgabewert geliefert wird. Einen Verweis auf das umgebende Element liefert das Attribut ownerElement.

Das Beispiel 112 zeigt die Ermittlung verschiedener Attribut-bezogener Informationen. Als Eingabe dient eine um die DOCTYPE-Deklaration erweiterte Variante der Projektverwaltung.
Zunächst werden alle Elemente des Typs Projekt in einer NodeList zusammengestellt. Danach werden alle Elemente der Knotenmenge durchlaufen, und im Falle der Existenz (geprüft mit hasAttributes) verschiedene Charakteristika des Attributs ausgegeben.
Während die Auswertungen zum ID-Attribut direkt aus dem XML-Eingabedokument ersichtlich sind, nutzt der XML-Prozessor zur Ermittlung der Informationen über budget die referenzierte Dokument Typ Deklaration. In ihr ist das genannte Attribut mit dem Vorgabwert 10000 definiert, der an die Applikation zurückgegeben wird, falls keine andere Belegung im Dokument gefunden wird. Dies ist für beide Projekt-Elemente der Fall.
Verfügt das Eingabedokument über keine DOCTYPE-Deklaration, so kann diese Information nicht ausgewertet werden.

Beispiel 16: Zugriff auf Attributinformation
Beispiel 112: Zugriff auf Attributinformation
(1)import org.w3c.dom.Attr;
(2)import org.w3c.dom.Document;
(3)import org.w3c.dom.Element;
(4)import org.w3c.dom.NodeList;
(5)import javax.xml.parsers.DocumentBuilder;
(6)import javax.xml.parsers.DocumentBuilderFactory;
(7)
(8)public class DOMExample5 {
(9)    public static void main(String[] args) throws Exception {
(10)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(11)        DocumentBuilder builder = factory.newDocumentBuilder();
(12)        Document document = builder.parse(args[0]);
(13)
(14)        Element theRootElement = document.getDocumentElement();
(15)
(16)        NodeList projects = theRootElement.getElementsByTagName("Projekt");
(17)
(18)        for (int i = 0; i < projects.getLength(); i++) {
(19)            Element theElement;
(20)            if ((theElement = (Element) projects.item(i)).hasAttributes()) {
(21)                Attr theAttribute = theElement.getAttributeNode("ID");
(22)                System.out.println("Attribute: " + theAttribute.getName());
(23)                System.out.println("value=" + theAttribute.getValue());
(24)                System.out.println("specified=" + theAttribute.getSpecified());
(25)
(26)                theAttribute = theElement.getAttributeNode("budget");
(27)                System.out.println("Attribute: " + theAttribute.getName());
(28)                System.out.println("value=" + theAttribute.getValue());
(29)                System.out.println("specified=" + theAttribute.getSpecified());
(30)            }//if
(31)        }//for
(32)    } //main()
(33)} //class DOMExample5
Download des Beispiels


ProcessingInstruction

Die Schnittstelle ProcessingInstruction erweitert Node um zwei Attribute zur Abbildung der Charakteristika einer XML-Verfahrensanweisung.
Die Graphik stellt diese als UML-Klassendiagramm dar:

Die DOM2-Schnittstelle Processing Instruction

Text

Die Schnittstelle Text erweitert CharacterData, die die basalen Operationen zur Manipulation von Zeichenketten definiert, geeignet um textuelle Inhalte eines XML-Dokuments darstellen zu können.
Die Graphik stellt diese als UML-Klassendiagramm dar:

Die DOM2-Schnittstellen CharacterData und Text

Das abschließende Beispiel zeigt die Nutzung aller vorgestellten Schnittstellen zur Konstruktion eines neuen XML-Dokuments.
Hierbei wird das in Abbildung 44 verwendete XML-Dokument vollständig durch DOM-Aufrufe im Hauptspeicher erzeugt und anschließend über die Standardausgabe ausgegeben.
Ebenso wie durch den Standard keine lesenden Operationen definiert werden, fehlt auch die symmetrische Möglichkeit zum Schreiben der erstellen Objektstrukturen. Die hierfür notwendigen Operationen werden in konkreten Implementierungen durch proprietären Code umgesetzt. Das vorliegende Beispiel nutzt daher die von SUN für die JDK-Implementierung vorgeschlagene (umständliche) Verfahrensweise der Erzeugung eines StreamResult-Objektes als Ergebnis der Dokumenttransformation mittels XSLT.

Beispiel 17: Erzeugung eines XML-Dokuments im Hauptspeicher
Beispiel 113: Erzeugung eines XML-Dokuments im Hauptspeicher
(1)import org.w3c.dom.Document;
(2)import org.w3c.dom.Element;
(3)import javax.xml.parsers.DocumentBuilder;
(4)import javax.xml.parsers.DocumentBuilderFactory;
(5)import javax.xml.transform.Transformer;
(6)import javax.xml.transform.TransformerFactory;
(7)import javax.xml.transform.dom.DOMSource;
(8)import javax.xml.transform.stream.StreamResult;
(9)
(10)public class DOMExample6 {
(11)    public static void main(String[] args) throws Exception {
(12)        // implementation specific part begins ...
(13)        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
(14)        DocumentBuilder builder = factory.newDocumentBuilder();
(15)        Document myDocument = builder.newDocument();
(16)        // ... ends
(17)
(18)        myDocument.appendChild(myDocument.createProcessingInstruction("myPI", "this is a test"));
(19)
(20)        Element htmlElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "html");
(21)        htmlElement.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
(22)        htmlElement.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");
(23)
(24)        myDocument.appendChild(htmlElement);
(25)
(26)        Element headElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "head");
(27)        htmlElement.appendChild(headElement);
(28)
(29)        Element titleElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "title");
(30)
(31)        titleElement.appendChild(myDocument.createTextNode("Testpage"));
(32)
(33)        headElement.appendChild(titleElement);
(34)
(35)        // this is the usual sequence ...
(36)        Element pElement = (Element) htmlElement.appendChild((myDocument.createElementNS("http://www.w3.org/1999/xhtml", "p")));
(37)        Element aElement = myDocument.createElementNS("http://www.w3.org/1999/xhtml", "a");
(38)        aElement.setAttribute("href", "http://www.jeckle.de");
(39)        aElement.appendChild(myDocument.createTextNode("link"));
(40)
(41)        pElement.appendChild(myDocument.createTextNode("This is a"));
(42)        pElement.appendChild(aElement);
(43)
(44)        Element svgElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:svg");
(45)        pElement.appendChild(svgElement);
(46)        svgElement.setAttribute("width", "4cm");
(47)        svgElement.setAttribute("height", "8cm");
(48)
(49)        Element ellipseElement = myDocument.createElementNS("http://www.w3.org/2000/svg", "svg:ellipse");
(50)        ellipseElement.setAttribute("cx", "2cm");
(51)        ellipseElement.setAttribute("cy", "4cm");
(52)        ellipseElement.setAttribute("rx", "2cm");
(53)        ellipseElement.setAttribute("ry", "1cm");
(54)
(55)        svgElement.appendChild(ellipseElement);
(56)
(57)        // implementation specific part begins ...
(58)        TransformerFactory transFactory = TransformerFactory.newInstance();
(59)        Transformer myTransformer = transFactory.newTransformer();
(60)        DOMSource src = new DOMSource(myDocument);
(61)        myTransformer.transform(src, new StreamResult());
(62)        // ... ends
(63)    } //main()
(64)} //class DOMExample6
Download des Beispiels


Das Beispiel zeigt die unzureichende Berücksichtigung der Namensräume in der aktuellen DOM2-Spezifikation. So werden die Namensraumdeklarationen wie Attribute durch setAttribute-Operationen den entsprechenden Elementen hinzufügt. Als Voraussetzung dieser Mimik muß die Implementierung daher gezielt ungültige XML-Bezeichner (Verstoß gegen das Verbot Element- und Attributnamen mit xml beginnen zu lassen) gestatten.
Ebenso ist die Übergabe qualifizierter Namen bei der Elementerzeugung (createElementNS) im selben Maße fehlerträchtig, da sie ungeprüft die literale Angabe des Namensraumpräfixes erfordert. Undefinierte Präfixe können hierbei zu ungültigen Dokumenten führen.

Anmerkung: Das die Erweiterung der Methode createElement um Namespacefunktionalität zu einer Methode neuen Namens (createElementNS führt mag den mit Überladungspolymorphie „aufgewachsenen“ Anwender objektorientierter Sprachen wie Java oder C++ zunächst verwundern. Hier offenbart sich jedoch nochmals die Unabhängigkeit der DOM-Schnittstelle, die gezielt keine Annahmen über eine technische Umsetzung trifft und daher in diesem Falle die möglicherweise nutzbare Polymorphie zu Gunsten der sprachunabhängigket vernachlässigt.

Ausblick auf DOM Level 3

Die nächste erweiternde Überarbeitung der DOM-Schnittstelle wird u.a. weitere speziell auf XML zugeschnittene Funktionalität bieten.
Darunter Operationen zur Ermittlung der Verwaltungsdaten eines XML-Dokuments, wie Version (public String getVersion()), Inhalt der Standalone-Deklaration (public boolean getStandalone()) sowie zur Abfrage des verwendeten Zeichenschemas (public String getEncoding()).
Diese Spezifikationen befinden sich jedoch noch im Status eines Working Drafts und liegen nur unvollständig in verfügbaren Implementierungen vor.

Abschlußbemerkungen und Einsatzempfehlungen

Mit den im W3C Document Object Model versammelten Schnittstellen lassen sich XML-strukturierte Dokumente durch eine generische Schnittstelle vergleichsweise einfach vollständig im Hauptspeicher halten und manipulieren.
Jedoch offenbart sich die Generizität der Schnittstelle allzuoft als Hemmschuh im praktischen Einsatz. Dies liegt einerseits in der entstehenden Lücke zwischen dem DOM-Typsystem und den Applikationsobjekten begründet, die eine explizite Abbildung oder Konvertierung zur Laufzeit erfordern. Darüberhinaus gibt das Objektmodell des DOM Traversierungswege vor, ohne Möglichkeiten zur konformen Erweiterung anzubieten.
Die entstehenden Speicherobjekte sind daher nur bedingt als Datenstrukturen der Applikation geeignet.
Zusätzlich konsumiert der Aufbau der DOM-Instanz mitunter beachtliche Speichermengen, was sich bei wachsender Dokumentgröße durchaus als Laufzeitproblem bemerkbar machen kann. Konkret ist das Skalierungsverhalten des DOM hinsichtlich Speicher und Laufzeit deutlich höher als bei vergleichbaren SAX-Implementierungen.
Generell gilt es im praktischen Einsatz die Abwägung zwischen angestrebtem Modifkationsumfang und Lesegeschwindigkeit anzustellen. Während die Vorteile des DOM klar auf Seiten der Änderbarkeit -- bis hin zur kompletten Erstellung vollständiger XML-Dokumente im Hauptspeicher -- liegt, gewinnt SAX durch sein planbares Laufzeit- und Speicherplatzverhalten.
Der nachfolgende Abschnitt stellt einige Laufzeit- und Speicherplatzuntersuchungen zusammen.

Web-Referenzen 2: Weiterführende Links
Web-Referenzen 18: Weiterführende Links
DOM-Implementierungen:
SmallTalk
JAXP @ SUN.com (Java)
DOM4J (Java)
JDOM Java Specification Request (JSR 102)
JDOM (Java)
XML4J (Java)
PyXML (Python)


3.3   Extrahierende Parser

Neben den beiden bisher vorgestellten API- und Parsertypen konnte sich in jüngerer Zeit ein neuer Ansatz zur lesenden Verarbeitung von XML-Dokumenten durch Programmiersprachen etablieren: die sogenannten extrahierenden Parser (engl. pull parser).
Ihr Verarbeitungsmodell wurde gezielt im Kontrast zu den bisher vorgestellten Mechanismen entwickelt. Während SAX und DOM XML-Eingaben verarbeiten ohne dabei dem Anwender den Eingriff in den Fluß der Verarbeitung zu gestatten, d.h. der Kontrollfluß wird nicht mehr explizit durch den Code im Programm definiert, sondern wird zur Ausführungszeit durch die Struktur des verarbeiteten XML-Dokuments bestimmt. Im Falle des SAX-Modells spiegelt sich dieser Fluß in der Reihenfolge der durch den Parser aufgerufenen Call-back-Routinen wieder, während im Verlauf der Baumkonstruktion eines DOM-basierten Parsers keinerlei Eingriffsmöglichkeiten für den Programmierer vorgesehen sind.

Extrahierende Parser kehren dies Paradigma um. Sie definieren eine Schnittstelle um innerhalb des Programmflusses aktiv Inhalte eines XML-Dokumentes zu extrahieren. Allerdings erfolgt der Zugriff hierbei nicht wahlfrei wie beispielsweise bei der Ergebniskonstruktion eines XPath- oder XQuery-Ausdruckes, sondern konsekutiv entlang der Reihenfolge der einzelnen Primitive im XML-Dokument.
Dieses Verhalten ist daher weniger mit einer Anfrage, als eher mit dem Vorrücken eines Dateizeigers bei linearer Konsumption vergleichbar.

Definition 16: Extrahierender Parser
Definition 16: Extrahierender Parser
Ein extrahierender Parser gestattet dem Programmierer die konsekutive lesende Verarbeitung der einzelnen Primitive eines XML-Dokuments gemäß der Dokumentordnung.


Gegenwärtig liegen Pull-Parser sowohl für die Java-Sprachwelt vor, als auch eine Implementierung als Bestandteil des Microsoft .NET-Frameworks. Jedoch konnte sich für diese Art der Verarbeitung noch kein allgemein anerkanntes und unterstütztes API herausbilden. Lediglich die Common API for XML Pull Parsing (XPP) konnte im Java-Umfeld einige Bedeutung erlangen und ist bereits ein ersten Umsetzungen verfügbar. Dieser Schnittstellenvorschlag bildet auch die Grundlage eines Standardisierungsansatzes (JSR 173) im Rahmen des Java Community Processes.
Das vorliegende Kapitel stützt sich auf eine Implementierung dieser API die unter dem Namen XPP3/MXP1kostenfrei verfügbar ist.

Das XPP-API definiert zur Verwaltung mindestens die folgenden Schnittstellen:

Bereits diese Übersicht zeigt als einen ersten wesentlichen Unterschied zu den klassischen Parserschnittstellen, daß innerhalb der XPP-API Wert auf die standardisierung der Infrastruktur zur Erzeugung des Parsers sowie die Darstellung auftretender Fehler gelegt wurde.

Zur Extraktion der Inhalte eines XML-Dokuments sieht die XPP-Schnittstelle folgende durch Instanzen der Klasse XmlPullParser umgesetzte Methoden vor:

Beispiel 18: Eine einfache XPP-basierte Applikation
Beispiel 114: Eine einfache XPP-basierte Applikation
(1)import org.gjt.xpp.XmlPullParser;
(2)import org.gjt.xpp.XmlPullParserException;
(3)import org.gjt.xpp.XmlPullParserFactory;
(4)import java.io.FileNotFoundException;
(5)import java.io.FileReader;
(6)import java.io.IOException;
(7)
(8)public class XPPsimple {
(9)    public static void main(String argv[]) {
(10)        try {
(11)            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
(12)            factory.setNamespaceAware(true);
(13)            XmlPullParser xpp = factory.newPullParser();
(14)            xpp.setInput(new FileReader(argv[0]));
(15)
(16)            int eventType;
(17)            while ((eventType = xpp.next()) != xpp.END_DOCUMENT) {
(18)                if (eventType == xpp.START_TAG)
(19)                    System.out.println("element started");
(20)                if (eventType == xpp.END_TAG)
(21)                    System.out.println("element ended");
(22)            } //while
(23)        } catch (XmlPullParserException e) {
(24)            e.printStackTrace();
(25)        } catch (FileNotFoundException e) {
(26)            e.printStackTrace();  
(27)        } catch (IOException e) {
(28)            e.printStackTrace();  
(29)        } //try
(30)    } //main()
(31)} //class XPPsimple
Download des Beispiels


Der Code des Beispiels 114 zeigt die Nutzung der XPP-API.
Zunächst wird in Zeile 11 eine Parser-Fabrik zur späteren Erzeugung des tatsächlichen Parsers erzeugt. Diese wird durch Aufruf der Methode setNamespaceAware dahingehend parametrisiert, daß die von ihr zur Verfügung gestellten Parser in einem Modus konform zur Namensraumspezifikation arbeiten.
In Zeile 13 wird von der Fabrik eine neue Parserinstanz angefordert deren Eingabekanal auf die als Kommandozeilenparameter übergebene Datei gelenkt wird (Zeile 14).
Die Extraktion der einzelnen Bestandteile des Eingabedokuments vollzieht sich in der Schleife ab Zeile 17. Dort wird, solange nicht das Ereignis END_DOCUMENT gelesen wurde, mittels Aufruf der Methode next ein weiteres Ereignis aus dem XML-Eingabestrom angefordert.
Nach Feststellung des Ereignistyps (Zeilen 18 und 20) kann eine Verarbeitung der mit dem Ereignis verknüpften XML-Primitive erfolgen.

Einschließlich der im Beispiel verwendeten Ereignistypen unterstützen XPP-konforme Parser folgende Ereignistypen:

Der Code des Beispiels 115 setzt eine Anwendung zur Zählung des Auftretens der einzelnen XML-Primitive auf der Basis eines extrahierenden Parsers um. Damit stellt das Programm eine Re-Implementierung der in Beispiel 98 auf Basis des SAX-APIs gezeigten Funktionalität dar.

Beispiel 19: Zählung der einzelnen XML-Primitive
Beispiel 115: Zählung der einzelnen XML-Primitive
(1)import org.gjt.xpp.XmlPullParser;
(2)import org.gjt.xpp.XmlPullParserException;
(3)import org.gjt.xpp.XmlPullParserFactory;
(4)import java.io.FileReader;
(5)import java.io.IOException;
(6)
(7)public class XPPsample3 {
(8)    public static void main(String argv[]) {
(9)        try {
(10)            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
(11)            factory.setNamespaceAware(true);
(12)            XmlPullParser xpp = factory.newPullParser();
(13)            xpp.setInput(new FileReader(argv[0]));
(14)            int eventType;
(15)            int startDocument = 1;
(16)            int endDocument = 0;
(17)            int startTag = 0;
(18)            int endTag = 0;
(19)            int elementContent = 0;
(20)            do {
(21)                eventType = xpp.next();
(22)                if (eventType == xpp.END_DOCUMENT) {
(23)                    endDocument++;
(24)                } else if (eventType == xpp.START_TAG) {
(25)                    startTag++;
(26)                } else if (eventType == xpp.END_TAG) {
(27)                    endTag++;
(28)                } else if (eventType == xpp.CONTENT) {
(29)                    elementContent++;
(30)                } //if
(31)            } while (eventType != xpp.END_DOCUMENT);
(32)            System.out.println("# startDocument events:" + startDocument + "\n" +
(33)                    "# endDocument events:" + endDocument + "\n" +
(34)                    "# startTag events:" + startTag + "\n" +
(35)                    "# endTag events:" + endTag + "\n" +
(36)                    "# element content events:" + elementContent + "\n"
(37)            );
(38)
(39)        } catch (XmlPullParserException e) {
(40)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(41)            e.printStackTrace();
(42)        } catch (IOException e) {
(43)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(44)            e.printStackTrace();
(45)        } //try
(46)    } //main()
(47)} //class XPPsample3
Download des Beispiels


Insbesondere im Vergleich zum ereignisbasierten Lesen unter Nutzung der SAX-Schnittstelle fällt die veränderte Umsetzung auf. So muß der Gesamtablauf nun nicht mehr in verschiedene Methoden aufgespalten werden, die durch den Parser aufgerufen werden, sondern kann innerhalb einer Methode realisiert werden.
Aus diesem Grunde kann auch die konzeptionell suboptimale Verwendung globaler Variablen unterbleiben.
Im Code fällt die Initialisierung der Zählvariable startDocument mit 1 auf (Zeile 15). Diese wird notwendig, da die verwendete Parserimplementierung keine Extraktion von START_DOCUMENT leistet weil dieses Ereignis immer implizit vor dem Start des Extraktionsvorganges anliegt.

Beispiel 20: Häufigkeitsermittlung einzelner Elementnamen
Beispiel 116: Häufigkeitsermittlung einzelner Elementnamen
(1)import org.gjt.xpp.XmlPullParserFactory;
(2)import org.gjt.xpp.XmlPullParser;
(3)import org.gjt.xpp.XmlPullParserException;
(4)import java.util.HashMap;
(5)import java.io.FileReader;
(6)import java.io.FileNotFoundException;
(7)import java.io.IOException;
(8)
(9)public class XPPsample2 {
(10)    private static final Integer ONE = new Integer(1);
(11)
(12)    public static void main(String argv[]) {
(13)        try {
(14)            HashMap elementHM = new HashMap();
(15)            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
(16)            factory.setNamespaceAware(true);
(17)            XmlPullParser xpp = factory.newPullParser();
(18)            xpp.setInput(new FileReader(argv[0]));
(19)
(20)            int eventType;
(21)            Integer freq;
(22)            String qName;
(23)            while ((eventType = xpp.next()) != xpp.END_DOCUMENT) {
(24)                if (eventType == xpp.START_TAG) {
(25)                    qName = xpp.getNamespaceUri()+":"+xpp.getLocalName();
(26)                    freq = (Integer) elementHM.get(qName);
(27)                    elementHM.put(qName, (freq == null ? ONE : new Integer(freq.intValue() + 1)));
(28)                } //if
(29)            } //while
(30)
(31)            System.out.println("RESULT=" + elementHM);
(32)
(33)        } catch (XmlPullParserException e) {
(34)            e.printStackTrace();
(35)        } catch (FileNotFoundException e) {
(36)            e.printStackTrace();
(37)        } catch (IOException e) {
(38)            e.printStackTrace();
(39)        } //try
(40)    } //main()
(41)} //class XPPsample2
Download des Beispiels


Der Quellcode des Beispiels 116 entspricht funktional dem des Beispiels 99, er zählt die Auftretenshäufigkeit der Elemente in einem XML-Dokument.
Jedoch unterstreicht er -- insbesondere im Vergleich zum SAX-basierten Beispiel -- die Natur der XPP-Schnittstelle. Im vorliegenden Falle werden durch den Parser keine Methodenaufrufe durchgeführt, sondern die Extraktion und Verarbeitung der einzelnen Elemente des betrachteten XML-Dokuments obliegt ausschließlich der Verantwortung des Programmierers.

Fehlerbehandlung

Ausgehend von den vorstehend beschriebenen Ereignistypen läßt sich leicht eine Prüfung auf Wohlgeformtheit realisieren, welche typischerweise durch alle verfügbaren XPP-Implementierungen durchgeführt wird.
Allerdings können Verletzungen der grundlegenden XML-Strukturierungsregeln auch diesem Parsingmodell, wie auch für SAX, nicht während eines nach außen abgeschlossenen Aufrufs erkannt werden, sondern offenbaren sich erst im Verlaufe des Extraktionsvorganges.

Beispiel 21: Behandlung einer XmlPullParserException
Beispiel 117: Behandlung einer XmlPullParserException
(1)import org.gjt.xpp.XmlPullParser;
(2)import org.gjt.xpp.XmlPullParserException;
(3)import org.gjt.xpp.XmlPullParserFactory;
(4)import java.io.FileReader;
(5)import java.io.IOException;
(6)
(7)public class XPPsample4 {
(8)    public static void main(String argv[]) {
(9)        XmlPullParser xpp = null;
(10)        try {
(11)            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
(12)            factory.setNamespaceAware(true);
(13)            xpp = factory.newPullParser();
(14)            xpp.setInput(new FileReader(argv[0]));
(15)            int eventType;
(16)            while ((eventType = xpp.next()) != xpp.END_DOCUMENT) {
(17)            } //while
(18)        } catch (XmlPullParserException e) {
(19)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(20)            System.out.println("Error occured at line: " + xpp.getLineNumber() + " at column " + xpp.getColumnNumber());
(21)            e.printStackTrace();
(22)        } catch (IOException e) {
(23)            System.out.println("EXCEPTION CAUGHT: " + e.getClass().getName());
(24)            e.printStackTrace();
(25)        } //try
(26)    } //main()
(27)} //class XPPsample4
Download des Beispiels
Download der Ergebnisdatei


Führt man den Code des Beispiels 117 mit dem Eingabedokument des Beispiels 10 aus, erzeugt der Parser folgende Ausnahme:

(1)EXCEPTION CAUGHT: org.gjt.xpp.impl.tokenizer.TokenizerException
(2)Error occured at line: 3 at column 17
(3)org.gjt.xpp.impl.tokenizer.TokenizerException: attribute value must start with double quote or apostrophe not 'a' at line 3 and column 17 seen "...<root>\r\n\t<elementA att"...
(4)        at org.gjt.xpp.impl.tokenizer.Tokenizer.next(Tokenizer.java:1156)
(5)        at org.gjt.xpp.impl.pullparser.PullParser.next(PullParser.java:392)
(6)        at XPPsample4.main(XPPsample4.java:23)
Web-Referenzen 3: Weiterführende Links
Web-Referenzen 19: Weiterführende Links
XML Pull Parsing -- Übersicht der API sowie Verweis auf verschiedene Implementierungen
N. Bornstein: Pull Parsing in C# and Java
Vergleich zwischen SAX2- und XPP-basierten Parsern


3.4   Nahtlose Integration von XML und Hochsprache -- Java XML Data Binding

Einen neuartigen Ansatz zur Integration zwischen XML-basierter Datenbeschreibung und applikationsinternen Objektstrukturen stellen die sog. data bindings für XML dar. Sie stellen anders als die Schnittstellen DOM und SAX keine Sammlung abstrakter Zugriffsroutinen dar, sondern leiten aus einer XML-Grammatik vokabularspezifische Speicher- und Verarbeitungsstrukturen ab. Zur Erreichung dieses Ziels werden aus einer als DTD oder XML-Schema vorliegenden Grammatik programmiersprachliche Konstrukte, etwa Klassendefinitionen und darauf operierende Methoden, erzeugt, die in eigene Applikationen eingebunden werden können.
Damit ist dieses datenorientierte Vorgehen deutlich abgrenzbar gegenüber ausführungsgetriebenen generischen Schnittstellen.

Mit der XML Data Binding Specification für Java liegt ein erster Ansatz zur Standardisierung vor, der sich sowohl der Ableitung der datenspeichernden Klassenstrukturen als auch den darauf operierenden Methoden widmet und für diese Referenzimplementierungen vorgibt. Die so erzeugten Datenstrukturen gestatten die direkte Verarbeitung der in einem schemakonformen Dokument abgelegten Daten in einer Java-Applikation.
Aktuell sind neben der Beschreibung des Spezifikationsvorhabens bereits erste Implementierungen verfügbar.
Die nachfolgenden Aussagen beziehen sich auf die frei zugängliche (Open Source) Implementierung Castor welche bereits große Teile der angestrebten Mächtigkeit abdeckt.

Abbildung 53 zeigt die einzelnen Schritte zur Erstellung der Java-Quelldateien aus einem XML-Schema.
Hierbei werden durch eine Schema-Compiler genannte Softwarekomponente aus dem XML-Schema zunächst Java-Klassen im Quellcode erzeugt. Ausgehend von diesem generierten Code kann die eigene Implementierung aufsetzen, die gemäß dem klassischen Java-Build-Compile-Zyklus verläuft.

Schritte zur Generierung einer Java-Implementierung aus einem XML-Schema

Zusätzlich zu den statischen Klassenstrukturen erzeugt der Schema-Compiler einige Methoden, die zum lesenden und schreibenden Zugriff auf die XML-Eingangsdaten benötigt werden. Dazu zählen Methoden zur Abfrage existierender Elemente und Attribute ebenso wie Codeteile, die das Erzeugen neuer Anteile oder das Entfernen bestehender gestatten.
Zusätzlich werden mit den Methoden marshal bzw. unmarshal Routinen zur Verfügung gestellt, die ein gegebenes schemakonformes XML-Dokument in den Hauptspeicher abbilden, bzw. das Ausschreiben der speicherresidenten Objekte als XML-Datei umsetzen.

Im einzelnen geschieht die Abbildung der XML-Schemastrukturen auf Java-Klassen wie folgt:

Nachfolgend wird die zuvor abstrakt dargestellte Generierung am Beispiel des Projektverwaltungsschemas diskutiert.

Vereinfachte Struktur der Projektverwaltungsschemas

Die Abbildung 54 stellt vereinfacht den strukturellen Aufbau des Projektverwaltungsschemas dar. Dabei wurden alle Elemente, Attribute sowie die Definitionen komplexer und simpler Typen berücksichtigt. Syntaktische Besonderheiten ohne Beitrag zur Struktur, wie die Unterscheidung zwischen direkt eingebetteter Definition und Referenzierung, wurden nicht berücksichtigt.

Der Schema-Compiler erzeugt daher aus dem Projektverwaltungsschema folgende Java-Quellcode-Dateien (JavaDoc-Dokumentation der erzeugten Klassen):

Aus den Elementen:

Aus den komplexen Typen:

Zusätzlich wird für den Inhalt des Elements Qualifikationsprofil die Klasse QualifikationsprofilTypeItem.java erzeugt. Sie resultiert aus dem im XML-Schema definierten Auswahlinhaltsmodell, das entweder ein Element des Typs Qualifikation oder Leistungsstufe zuläßt.

Die im XML-Schema verwendeten Datentypen werden durch den Generierungsprozeß auf die verfügbaren Java-internen Datentypen abgebildet, soweit sinnvoll möglich. Für alle anderen XSD-Typen liefert die Castor-Laufzeitbibliothek eigene Implementierungen.
Die Abbildungen der XML-Schematypen auf die entsprechenden Programmierspachenkonstrukte kann Tabelle 28 entnommen werden.

Tabelle  28: Abbildung der XML-Schemadatentypen auf die der Castor-Laufzeitbibliothek
Tabelle 28: Abbildung der XML-Schemadatentypen auf die der Castor-Laufzeitbibliothek
XML-Schemadatentyp
Java-Castor-Typ
java.lang.String
boolean (Java-Primitivtyp)
java.math.BigInteger
float (Java-Primitivtyp)
double (Java-Primitivtyp)
java.util.Date
org.exolab.castor.types.Time
org.exolab.castor.types.GYearMonth
org.exolab.castor.types.GYear
org.exolab.castor.types.GMonthDay
org.exolab.castor.types.GDay
org.exolab.castor.types.GMonth
byte[] (Array des Java-Primitivtypen)
byte[] (Array des Java-Primitivtypen)
java.lang.String
java.lang.String
java.lang.String
java.lang.String
java.util.Vecotor mit Elementen des Typs NMTOKEN
java.lang.String
java.lang.String
java.lang.Object
java.util.Vector mit Elementen des Typs IDREF
int
int
int
long
int
int
byte
int
int


Darüberhinaus erzeugt der Schema-Compiler aus der Typdefinition der Gehaltsgruppe eine separate Klasse zur Behandlung dieses selbstdefinierten Datentyps.

Die Applikation des Beispiels 118 zeigt die Implementierung des Einlesevorganges mit den durch Castor generierten Rahmenklassen.
Der gesamte Lese- und Validierungsvogang wird durch die Methode unmarshal realisiert. Sie liest eine XML-Datei aus einem Eingabestrom und erzeugt dabei die notwendigen Speicherobjekte und belegt sie mit der eingelesenen Information.
Tritt während dieses Vorganges ein Fehler auf, so wird eine MarshalException ausgelöst. Diese Situation entspricht einem Validierungsfehler beim Prüfvorgang des zugrundeliegenden XML-Schemas.
Dual zum Lesevorgang erlaubt die Methode marshal das Ausschreiben der Speicherobjekte als XML-Datei. Hierbei ist es unerheblich, ob diese Hauptspeicherstrukturen durch einen vorhergehenden unmarshal-Aufruf erzeugt wurden, oder mit programmiersprachlichen Mitteln innerhalb der Applikation instanziiert wurden.

Beispiel 22: Einlesen einer XML-Datei mit Castor
Beispiel 118: Einlesen einer XML-Datei mit Castor
(1)import java.io.*;
(2)import org.exolab.castor.xml.MarshalException;
(3)import TestApp.*;
(4)
(5)public class CastorExample1 {
(6)    public static void main(String[] argv) {
(7)        try {
(8)            ProjektVerwaltung myPv = ProjektVerwaltung.unmarshal(new FileReader(argv[0]));
(9)            //...
(10)            myPv.marshal(new FileWriter(argv[1]));
(11)        } //try
(12)        catch (MarshalException e) {
(13)            Exception originatingException = e.getException();
(14)            if (originatingException != null) {
(15)                System.out.println(originatingException);
(16)            } //if
(17)        } //catch
(18)        catch (Exception e) {
(19)            System.out.println("EXCEPTION: " + e);
(20)        }
(21)    } //main()
(22)} //class CastorExample1
Download des Beispiels


Die Graphik 55 faßt nochmals die beiden Einzelschritte des Quellcodes aus Beispiel 118 und den Klassengenerierungsschritt zusammen.

Entwicklungs- und Laufzeitoperationen mit dem Castor-Rahmenwerk

Zur Verarbeitung der speicherresidenten Javaobjekte werden durch den Schema-Compiler eine Reihe Standardmethoden erzeugt, welche den einfachen und uniformen Zugriff auf die verschiedenen Informationen ermöglichen.
Im Einzelnen sind dies:

Tabelle  29: Leseoperationen des Castor Data Bindings
Tabelle 29: Leseoperationen des Castor Data Bindings
Operation
Beispiel
Funktionalität
get...()
Liefert den Inhalt des Attributs oder Elements.
Der Ergebnisdatentyp entspricht hierbei dem Datentyp gemäß der Abbildungsvorschriften aus Tabelle 28
getContent()
Liefert den textartigen Inhalt eines Knotens.
Diese Form findet ausschließlich für Elemente mit gemischtem Inhalt Anwendung.
get...Count()
Liefert die Anzahl der Kindknoten eines gegebenen Typs.
get...(int index)
Liefert das n-te Element des entsprechenden Typs zurück.
Im XML-Dokument entspricht dies dem n-ten Kindknoten.
enumerate...()
Liefert alle Kindknoten des gegebenen Typs als Java-Collection.
has...()
Liefert für Attribute mit Vorgabewertdefinition die Information, ob der Wert aus dem Dokument übernommen wurde oder anhand der im XML-Schema definierten Vorgabebelegung gesetzt wurde.
isValid()
Liefert als Wahrheitswert, ob das Objekt einschließlich seiner referenzierten Objekte in ein Schema-gültiges XML-Dokument abgebildet werden kann.


Beispiel 119 zeigt die verschiedenen vorgestellten Leseoperationen.
Zunächst wird mittels der Methode getPersonCount() die Anzahl der Kindknoten des Typs Person unterhalb des Wurzelknotens Projektverwaltung ermittelt. Anschließend werden alle Knoten des genannten Typs einzeln mittels der Methode getPerson(...) nach dem Inhalt des Attributs PersID angefragt.
Der Zugriff auf die Elemente des Typs Vorname vollzieht sich in analoger Weise. Aufgrund des möglichen mehrfachen Auftretens der Vornamen-Elemente innerhalb eines Personen-Knotens erfolgt hier eine zweite Iteration innerhalb der Schleife über alle Personen.
Abschließend zeigt der Zugriff auf die Elemente des Typs Qualifikationsprofil die Verwendung der Java-Collection-API, welche ein vereinfachtes Durchlaufen aller verwalteten Elemente gestattet. Zusätzlich veranschaulicht die letzte Sequenz den Lesevorgang for ein Element mit gemischtem Inhaltsmodell.

Beispiel 23: Auslesen von Attribut- und Elementinformation
Beispiel 119: Auslesen von Attribut- und Elementinformation
(1)import TestApp.*;
(2)import TestApp.types.*;
(3)import org.exolab.castor.xml.MarshalException;
(4)import java.io.FileReader;
(5)import java.util.Enumeration;
(6)
(7)public class CastorExample2 {
(8)    public static void main(String[] argv) {
(9)        try {
(10)            ProjektVerwaltung myPv = ProjektVerwaltung.unmarshal(new FileReader(argv[0]));
(11)
(12)            //attribute
(13)            for (int i = 0; i < myPv.getPersonCount(); i++)
(14)                System.out.println(myPv.getPerson(i).getPersID());
(15)
(16)            //element
(17)            Person pers;
(18)            for (int i = 0; i < myPv.getPersonCount(); i++) {
(19)                pers = myPv.getPerson(i);
(20)                for (int j = 0; j < pers.getVornameCount(); j++)
(21)                    System.out.println(pers.getVorname(j));
(22)            } //for
(23)            pers = null;
(24)
(25)            //mixed content
(26)            System.out.println(myPv.getPerson(1).getQualifikationsprofil().getContent());
(27)
(28)            Enumeration e = myPv.getPerson(1).getQualifikationsprofil().enumerateQualifikationsprofilTypeItem();
(29)            Object qti;
(30)            while (e.hasMoreElements()) {
(31)                qti = e.nextElement();
(32)                System.out.println(((QualifikationsprofilTypeItem) qti).getLeistungsstufe());
(33)                System.out.println(((QualifikationsprofilTypeItem) qti).getQualifikation());
(34)            } //while
(35)        } //try
(36)        catch (MarshalException e) {
(37)            Exception originatingException = e.getException();
(38)            if (originatingException != null) {
(39)                System.out.println(originatingException);
(40)            } //if
(41)        } //catch
(42)        catch (Exception e) {
(43)            System.out.println("EXCEPTION: " + e);
(44)        }
(45)    } //main()
(46)} //class CastorExample2
Download des Beispiels


Tabelle  30: Schreiboperationen des Castor Data Bindings
Tabelle 30: Schreiboperationen des Castor Data Bindings
Operation
Beispiel
Funktionalität
set...(...)
Setzt den Inhalt des Attributs.
Der Übergabedatentyp entspricht hierbei dem Datentyp gemäß der Abbildungsvorschriften aus Tabelle 28
add...(...)
Fügt ein neues Element hinzu.
set...(int index, ...)
Fügt ein neues Element an der gegebenen Indexposition ein.
setContent(s java.lang.String)
Setzt den textartigen Inhalt eines Knotens.
Diese Form findet ausschließlich für Elemente mit gemischtem Inhalt Anwendung.
remove...(...)
Löscht das übergebene Element.
clear...()
Leert das angegebene Element.


Der Code des Beispiels 120 zeigt die verschiedenen Operationen zur Erzeugung von Attribut- und Elementinhalten.
Als Besonderheit wird zur Belegung des Attributs Gehaltsgruppe auf eine durch das Rahmenwerk erzeugte Konstante zurückgegriffen, welche die typkonforme Belegung dieses Attributs sicherstellt.

Beispiel 24: Erzeugung von Attribut- und Elementinhalten
Beispiel 120: Erzeugung von Attribut- und Elementinhalten
(1)import TestApp.*;
(2)import TestApp.types.*;
(3)import org.exolab.castor.xml.MarshalException;
(4)import java.io.FileReader;
(5)import java.io.FileWriter;
(6)
(7)public class CastorExample3 {
(8)    public static void main(String[] argv) {
(9)        try {
(10)            ProjektVerwaltung myPv = ProjektVerwaltung.unmarshal(new FileReader(argv[0]));
(11)
(12)            //set existing attribute
(13)            myPv.getPerson(1).setPersID("ID001");
(14)
(15)            //set existing element
(16)            myPv.getPerson(0).setNachname(0, "Schulze");
(17)
(18)            //create attribute
(19)            myPv.getPerson(1).setGehaltsgruppe(GehaltsgruppeType.VALUE_1);
(20)
(21)            myPv.marshal(new FileWriter(argv[1]));
(22)        } //try
(23)        catch (MarshalException e) {
(24)            Exception originatingException = e.getException();
(25)            if (originatingException != null) {
(26)                System.out.println(originatingException);
(27)            } //if
(28)        } //catch
(29)        catch (Exception e) {
(30)            System.out.println("EXCEPTION: " + e);
(31)        }
(32)    } //main()
(33)} //class CastorExample3
Download des Beispiels


Abschlußbemerkungen und Einsatzempfehlungen

Konzeptionell entwickelt der Data Binding-Ansatz die bereits mit dem Document Object Model verwirklichte Grundidee einer Speicherabbildung von XML-Dokumenten fort. Anders als im DOM sind jedoch auch die Schnittstellen zum Einlesen und Schreiben der XML-Dateien definiert.
Jedoch stellt der vorgestellte Ansatz als Teil des Java Community Process keinen offenen Standard dar, sondern lediglich einen im SUN-Umfeld verfolgten Vorschlag, der bisher nur für die Programmiersprache Java Umsetzung gefunden hat.
In der Anwendung offenbart sich der Ansatz zur Generierung problemspezifischer Klassenstrukturen aus XML-Schemata als durchaus gangbar. Zusätzlich positiv wirken sich die erzeugten Objekte in der Handhabung aus, da aufwendige Typkonversionen (wie bei den generischen DOM-Typen in der Regel immer notwendig) zwischen Serialisierungsformat und Applikationsdatenhaltung entfällt.

Web-Referenzen 4: Weiterführende Links
Web-Referenzen 20: Weiterführende Links


3.5   Web Services

Motivation und Hintergrund

Stand Datenaustausch in der Betrachtung der Metasprache XML bisher nahezu ausschließlich im Zeichen datei- oder strombasierter Integration, so eröffnet das Einsatzgebiet der Web Services den Einsatz XML-basierter Sprachen zur Abwicklung Internet-basierter online Kommunikation zwischen Anwendungssystemen.

Dem Begriff Web Service war in jüngerer Zeit eine bemerkenswerte Karriere beschieden, so daß es ihm gelang in der Praxis beachtliches Interesse auf sich zu ziehen. Allerdings fehlt bisher eine einheitliche Definition dieses Terminus hinsichtlich Zielsetzung und technischer Inhalte. Vielmehr versuchten und versuchen namhafte Herstelle durch eine Reihe verschiedener Definitionen, die am Markt offen zueinander in Konkurrenz treten, bisherige Techniken mit dem Ansatz der Web Services zu verschmelzen.
Jedoch führt(e) diese Vorgehensweise weder zu einer einheitlichen Begriffsübereinkunft und daher in der Folge auch zu keiner brauchbaren Abgrenzung gegenüber existierenden Techniken --- wie CORBA, RMI oder DCOM --- im Umfeld.
Nachfolgend wird daher eine an die Ergebnisse der Web Service Architecture-Arbeitsgruppe des World Wide Web Konsortiums angelehnte Definition zugrunde gelegt:

Definition 17: Web Service
Definition 17: Web Service
Ein Web Service ist ein durch eine URI (gemäß RFC 2396) identifiziertes Softwaresystem, dessen öffentliche Schnittstellen und Protokollbindungen durch XML definiert und beschrieben sind.
Diese Definitionen können durch andere Softwaresysteme ermittelt und bezogen werden. Auf der Basis der publizierten Schnittstellendefinitionen können diese Systeme dann mit dem Web Service in der durch die Schnittstelle festgelegten Weise interagieren. Diese Interaktion geschieht durch den Austausch XML-basierter Nachrichten, die mittels Internetprotokollen übertragen werden.


Der Begriff des Service ist hierbei durchaus in Anlehnung an den klassischen Dienstleistungsbegriff gemeint. Dieser beschreibt Handlungen, die im Auftrag eines Dritten vorgenommen werden, welche kein physisches Gut produzieren, sondern deren Charakter ausschließlich durch die Handlungserbringung selbst definiert ist.

Die Definition enthält ferner bereits Aussagen über die Komponenten einer Web Service basierten Architektur (einer sog. serviceorientierten Architektur (SOA)) und deren technischer Realisierung. Grundlegend Eigenschaften einer solchen Architektur ist neben der XML-Basiertheit die Verwendung von Universal Resource Identifkatoren zur eineindeutigen Benennung eines angebotenen Dienstes sowie die Nutzung der bestehenden Internetinfrastruktur zur Datenübertragung. Der Begriff Internetinfrastruktur soll hierbei nicht verengt auf die Techniken des WWW, d.h. HTTP auf Basis TCP/IP, verstanden werden, sondern durchaus im Sinne des der Internetprotokollhierarchie gebraucht werden.

Gleichzeitig postuliert die Definition drei grundlegende Elemente einer serviceorientierten Architektur:

  1. Ein XML-basierte Protokoll zur Darstellung und zum Austausch der Daten zwischen Diensten und ihren Nutzern.
  2. Eine XML-basierte Beschreibungssprache zur Publikation von Dienstschnittstellen.
  3. Einen Dienst zur Verwaltung der publizierten Schnittstellenbeschreibungen.

Diese drei aufeinander aufsetzenden Dienstschichten deuten auch bereits drei typische Rollen innerhalb einer serviceorientierten Architektur an:

  1. Dienstanbieter.
    Er übernimmt die physische Bereitstellung des Dienstes, d.h. eine Implementierung und Publikation auf einem über das Internet zugänglichen Server.
    Zusätzlich kann er die Aufrufschnittstelle des Dienstes dokumentieren.
  2. Dienstnachfrager/-nutzer.
    Er nutzt den angebotenen Dienst durch Übermittlung XML-codierter Nachrichten über Internetprotokolle.
    Zusätzlich kann er vor der Erstnutzung die Schnittstellenbeschreibung aus einem allgemein zugänglichen Dienstverzeichnis beziehen.
  3. Dienstverzeichnis.
    Es verwaltet die durch die Dienstanbieter bereitgestellten kategorisierten Schnittstellenbeschreibungen.

Ausgehend von den Grundrollen und ihren Interaktionsbeziehungen ergeben sich die zwei in Abbildung 56 Abläufe für die Abwicklung einer Web Service-basierten Kommunikation.

Web Service Interaktionsszenarien

Die Abbildung hebt die optionalen Schritte zur Ermittlung der Schnittstellenbeschreibung blau hervor. Liegt diese dem Aufrufwilligen bereits vor oder ist die Schnittstelle ihm bereits bekannt, so kann auf den Bezug der im Dienstverzeichnis abgelegten Beschreibungsdaten verzichtet werden und der Dienstaufruf direkt erfolgen.
Die Schnittstellenbeschreibung nimmt damit keine herausragende Rolle innerhalb der Architekturerstellung ein, wie dies beispielsweise für CORBA, RMI oder DCOM der Fall wäre (dort ist die Schnittstellenbeschreibung Teil des Entwicklungszyklus und muß zum Übersetzungzeitpunkt des Aufrufclients zwingend vorliegen).

Aus der Kombination der Architekturelemente und der Interaktionsszenarien haben sich drei Standards am Markt etabliert, deren Implementierungen die dargestellten Grundaufgaben innerhalb einer serviceorientierten Architektur erfüllen:

Anmerkung: Ursprünglich wurde das Akronym SOAP zu Simple Object Access Protocol expandiert. Aufgrund der irreführenden Nähe zur objektorientierten Programmierung wurde jedoch im Verlauf des Standardisierungsprozesses beschlossen etablierte Akronym als Namen beizubehalten, jedoch von der weiteren Expansion abzusehen.

SOAP

SOAP, welches als Version 1.0 im Herbst 1999 als Ergebnis der Kooperation zwischen den Firmen DevelopMentor, IBM, Microsoft, Lotus und UserLand Software vorgestellt wurde markiert weniger den Beginn der Idee der Web Services, als vielmehr einen weiteren evolutionären Entwicklungsschritt.
Die Uridee die zur Abwicklung synchroner entfernter Funktionsaufrufe (Remote Procedure Calls (RPC)) zu übermittelnden Über- und Rückgabeparameter durch ein XML-Vokabular auszudrücken findet sich bereits im Protokoll XML-RPC verwirklicht.

Ausgehend von diesem Ansatz definiert SOAP in der Version 1.0 ein vollständiges Protokoll, welches neben der Übertragung von Nutzdaten auch die Darstellung von dekriptiver Verwaltungsinformation vorsieht. Wie bereits für XML-RPC ist auch bei SOAP v1.0 ausschließlich die Verwendung von HTTP als Transportprotokoll definiert.

Diese Beschränkung wird durch die Anfang 2001 freigegebene SOAP Version 1.1 aufgehoben, welche SOAP als vollständig von der zu tatsächlichen Übertragung gewählten Protokollschicht entkoppelt und damit als eigenständige Protokollabstraktion etabliert. Gleichzeitig führt diese Version die Möglichkeit asynchroner Aufrufe ein.

Um den SOAP-Ansatz einer breiten Interessentenschicht zugänglich werden zu lassen und auch die Sensibilisierung für eine mögliche Standardisierung des Protokolls zu schaffen reichen die beteiligten Partner die Spezifikationsversion 1.1 unverändert als W3C Note ein.

Die im Herbst 2000 begonne Standardisierungsarbeit durch die W3C XML Protocol Arbeitsgruppe übernahm den eingereichten Spezifikationsvorschlag der Version 1.1 weitestgehend und führte, aus Gründen der Interoperabiltität behutsame Korrekturen sowie umfangreiche Erweiterungen ein. Mit der Verabschiedung des endgültigen W3C-Standards ist im Laufe des Jahres 2003 zu rechnen.

Die Abbildung 57 stellt nochmals die einzelnen SOAP-Versionen, ihre Unterschiede und den Vorläufer XML-RPC in der chronologischen Übersicht zusammen.

Zeitliche Entwicklung des SOAP-Protokolls

Aufbau einer SOAP-Nachricht

Jede SOAP-Nachricht, unabhängig davon ob es sich um eine synchron oder asynchron übermittelte Anfrage oder Antwort handelt besteht generell aus zwei Teilen:

  1. Dem Rumpfelement (Body) zur Aufnahme der zu übermittelnden Nutzdaten.
  2. Optional einem oder mehreren Kopfelementen (Header) zur Aufnahme von Metainformation.

Das Beispiel 121 zeigt einen vollständigen SOAP-Aufruf.
Er besteht aus einem Umschlag (dargestellt durch das Element Envelope), der das beschreibende Kopfelement altertcontrol sowie die im Body-Element zusammengefaßten Nutzdaten enthält.

Alle durch den Standard vorgegebenen Elemente und Attribute sind dem Namensraum http://www.w3.org/2003/05/soap-envelope zugeordnet und alle Anwenderdefinierten den entsprechenden eigenen Namensräumen.

Beispiel 1: Ein vollständiger SOAP-Aufruf
Beispiel 121: Ein vollständiger SOAP-Aufruf
(1)<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
(2) <env:Header>
(3)  <n:alertcontrol xmlns:n="http://example.org/alertcontrol">
(4)   <n:priority>1</n:priority>
(5)   <n:expires>2001-06-22T14:00:00-05:00</n:expires>
(6)  </n:alertcontrol>
(7) </env:Header>
(8) <env:Body>
(9)  <my:message xmlns:my="http://www.mycompany.com">
(10)   <my:text>Hello World!</my:text>
(11)  </my:message>
(12) </env:Body>
(13)</env:Envelope>


Die Aufgabe der SOAP-Header ist es Verwaltungsinformation aufzunehmen, die nicht ausschließlich durch den Empfänger des SOAP-Aufrufes zu verarbeiten ist und die nicht Teil der Nutzdaten ist.
Beispiele hierfür sind Daten über das Routingverhalten, gesetzte Sperren oder Transaktionen aber auch Zugriffsdaten wie Nutzername und Passwort (diese natürlich verschlüsselt!).

Die Verarbeitung eines Kopfelements ist vorgabegemäß optional, außer das zusätzliche gesetzte Attribut mustUnderstand weißt den Wert 1 oder true (die beiden durch XML Schema zugelassenen lexikalischen Repräsentationen für logisch wahr) auf. In diesem Falle muß ein SOAP-Knoten das Kopfelement verarbeiten. Kann die Verarbeitung nicht vorgenommen werden, so muß an den Sender der SOAP-Nachricht eine Fehlermeldung übermittelt werden.
Ein SOAP-Knoten ist hierbei jeder Rechner entlang des Nachrichtenpfades zwischen Sender und Empfänger, der das SOAP-Protokoll verarbeiten kann.

Soll die Verarbeitung der SOAP-Kopfelemente auf einen bestimmten Rechner (beispielsweise einen zwischenspeichernden Proxy-Knoten) beschränkt werden, so kann durch das im Standard vorhergesehene Attribut role eine eineindeutige Adressierung eines durch URI identifizierten (Zwischen-)Knotens erreicht werden.
Das Beispiel 122 zeigt die Nutzung des role- und des mustUnderstand-Attributs.

Beispiel 2: Nutzung der SOAP-Kopfelemente
Beispiel 122: Nutzung der SOAP-Kopfelemente
(1)<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
(2)	<env:Header>
(3)   	<abc:Extension1
(4)    		xmlns:abc="http://example.org/2001/06/ext"
(5)      	env:mustUnderstand="true"
(6)      	role="http://www.example.com/xyz"/>
(7)    	<def:Extension2 xmlns:def="http://example.com/stuff"
(8)       	env:mustUnderstand="true"
(9)       	env:role="http://www.w3.org/2003/05/soap-envelope/role/next"/>
(10)	</env:Header>
(11)  	<env:Body>
(12)    	...
(13)  	</env:Body>
(14)</env:Envelope>


Das Beispiel zeigt die Nutzung zweier Kopfelemente (Extension1 und Extension2) in „eigenen“, d.h. nicht den im Standard vorgesehenen, Namensräumen.
Für beide Kopfelemente ist das Attribut mustUnderstand mit true belegt, was sie als zwingend zu prozessieren ausweist.
Zusätzlich ist für Extension2 das Attribut role auf http://www.example.com/xyz gesetzt. Diese Belegung charakterisiert die durch mustUnderstand formulierte verpflichtende Verarbeitung näher. Im vorliegenden Falle muß sie ausschließlich durch den mit der URI http://www.example.com/xyz bezeichnenden Zwischenknoten erfolgen, für alle anderen Knoten des Nachrichtenpfades --- einschließlich des endgültigen Empfängers --- kann dieses Kopfelement ignoriert werden. Der dieses Kopfelement verarbeitende SOAP-Knoten darf es nach erfolgreicher Prozessierung aus der SOAP-Nachricht entfernen.
Bei der für das zweite Kopfelement (Extension2) gewählten Rolle (http://www.w3.org/2003/05/soap-envelope/role/next) handelt es sich um eine durch die SOAP-Spezifikation vordefinierte URI, welche alle Knoten entlang des Nachrichtenpfades einschließlich dem endgültigen Empfänger selbst bezeichnet. In diesem Fall darf das Kopfelement, selbst nach erfolgreicher Verarbeitung durch einen Knoten nicht entfernt werden, da weitere Verarbeitungsschritte durch andere Knoten folgen können. (Sofern es sich nicht um den endgültigen Empfänger handelt, müssen sogar weitere Verarbeitungsschritte folgen.)

Neben der dargestellten Sonderbelegung des Rollenattributes definiert der SOAP-Standard des W3C mit http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver eine Attributbelegung, die Kopfelemente kennzeichnet die ausschließlich durch den endgültigen Empfänger einer Nachricht verarbeitet werden dürfen und durch http://www.w3.org/2003/05/soap-envelope/role/none Kopfelemente, die durch einen SOAP-Knoten nicht verarbeitet werden dürfen.

Durch die Kopfelemente können Einzelknoten entlang des Vermittlungspfades einer SOAP-Nachricht pauschal oder gezielt zu einer anwenderdefinierten Verarbeitung angeregt werden. Die aktiven Zwischenknoten übernehmen hierbei nicht mehr nur reine vermittelnde Aufgaben auf den tieferliegenden (Transport-)Protokollschichten, sondern werden zu aktiven Elementen der SOAP-Nachrichtenkette. Aufgrund ihrer Stellung im Nachrichtenpfad zwischen Sender und endgültigem Empfänger werden sie auch mit dem Begriff SOAP Intermediäre belegt.

Die Übertragung der zwischen Dienstnutzer und Dienst ausgetauschten Daten (d.h. Aufruf- und Rückgabeparameter oder Einwegbotschaft) erfolgt durch das Body-Element der SOAP-Nachricht.
Beispiel 123 zeigt den erzeugten SOAP-Datenstrom zum Aufruf eines Dienstes der die beiden int-Parameter a und b addiert und das Ergebnis zurückliefert.

Beispiel 3: Nutzung des SOAP-Rumpfelements
Beispiel 123: Nutzung des SOAP-Rumpfelements
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<env:Envelope
(3)	xmlns:env="http://www.w3.org/2003/05/soap-envelope"
(4)	xmlns:b="http://www.example.org/AddService>
(5) 	<env:Body>
(6)  		<b:add env:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
(7)   		<b:a>2</b:a>
(8)   		<b:b>3</b:b>
(9)  		</b:add>
(10) 	</env:Body>
(11)</env:Envelope>


Innerhalb des Body-Elements werden die benannten Parameter durch jeweils ein Element, das den Namen des Parameters trägt, dargestellt. Jedes Parameterelement enthält die lexikalische Repräsentation des zu übertragenden Wertes. Der aufgerufene Dienst (im Beispiel: add) fungiert als gemeinsames Elternelement der einzelnen Parameterelemente.
Zur Unterscheidung der verschiedenen Vokabularelemente des SOAP-Aufrufes müssen alle anwenderdefinierten Teile des Body-Elements einem eigenen, vom SOAP-Vorgabenamensraum abweichenden, Namensraum zugeordnet sein. Dies geschieht vor dem Hintergrund sowohl der gewünschten Abgrenzung von den durch den Standard vorgegebenen Elementen und Attributen, als auch mit der Zielsetzung zur Validierung der SOAP-Aufrufe eine XML-Schemainstanz einsetzen zu können. Hierzu sind die abweichenden Namensräume zwingend erforderlich, um mithilfe des any-Elements die Validierung der durch den SOAP-Standard strukturell nicht festlegbaren Body-Kindelemente zu ermöglichen.
Die Struktur dieser Kindelemente orientiert sich ausschließlich an der XML-Darstellung der für einen Service notwendigen Parameter und kann daher im allgemeinen Falle nicht durch den Standard vorgegeben werden. Aus diesem Grunde legt die SOAP-Spezifikation lediglich Encodierungsregeln zur Transformation hauptspeicherresidenter Objekte und Strukturen in eine XML-Darstellung fest.
Das Beispiel verwendet diese vordefinierten Encodierungsregeln, welche die Abbildung allgemeiner Objektgraphen in XML-Strukturen gestatten. Neben dieser, an der Belegung des Attributs encodingStyle mit http://www.w3.org/2003/05/soap-encoding erkennbaren, Serialisierungsform können durch den Anwender beliebige eigene Regeln zur Gewinnung der XML-Darstellung festgelegt werden. Einzig das im Standard definierte SOAP-Encoding muß jedoch zwingend von allen Implementierungen unterstützt werden.

In ähnlicher Darstellungsform der Anfrage findet sich auch die Übermittlung der durch den aufgerufenen Dienst berechneten Resultate codiert:

Beispiel 4: Nutzung des SOAP-Rumpfelements
Beispiel 124: Nutzung des SOAP-Rumpfelements
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<env:Envelope
(3)	xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
(4)	xmlns:b="http://www.example.org/AddService">
(5)	<env:Body>
(6)  		<b:result env:encodingStyle="http://www.w3.org/2003/05/soap-encoding">5</b:result>
(7) 	</env:Body>
(8)</env:Envelope>


Beispiel 124 zeigt die rückübermittelte Antwort des Addier-Dienstes.
Auch sie folgt den selben Struktur- und Erstellungsprinzipien. Daher weist auch Antwortnachricht die Trennung in (optionale und in diesem Beispiel nicht genutzte) Kopfelemente und nutzdatentragende Rumpfelemente als Kindelemente des Body-Elements auf.
Die Erstellung der XML-Darstellung erfolgt, wie bereits für den Aufruf, gemäß festgelegter bzw. anwenderdefiniert festlegbarer Richtlinien einer Encodierungsdarstellung. Auch in diesem Beispiel wurde die Standardencodierung gewählt, weshalb das encodingStyle-Attribut abermals mit dem Wert http://www.w3.org/2003/05/soap-encoding versehen ist.
Zur Abgrenzung von den durch den W3C-Standard vordefinierten Elementen muß auch zur Darstellung der Antwort eines Dienstaufrufs jedes Kindelement des Body-Knotens einen vom SOAP-Standard abweichenden Namensraum besitzen.
Die Organisation der Darstellung des Dienstergebnisses als XML-Dokument ist dem Diensterbringer überlassen. Im Beispiel wird ein Element result übertragen.

Quellcode des Web Service
Quellcode eines Web Serviceaufrufes

Fallstudie: Implementierung eines Web Services

Die nachfolgende Fallstudie betrachteten einen einfachen Web Service zur Realisierung der mathematischen Operationen auf dem Körper der komplexen Zahlen.
Die Diskussion wird an der frei verfügbaren SOAP-Implementierung Axis geführt, welche im Rahmen des Apache-Projekts gepflegt wird. Axis stellt eine vollständig in Java realisierte Bibliothek zur Umsetzung von Web Services die als Java-Klassen angeboten werden zur Verfügung.
Zur Ausführung wird eine beliebige Servlet-Umgebung benötigt. Für das Beispiel wurde die ebenfalls kostenfrei verfügbare Jakarta-Tomcat eingesetzt, welche als Ausführungsumgebung der Web Services dient.

Implementierung des Web Service:

Beispiel 5: Beispielwebdienst
Beispiel 125: Beispielwebdienst
(1)public class Complex {
(2)	private double re;
(3)	private double im;
(4)	
(5)	public Complex(double re, double im) {
(6)		this.re = re;
(7)		this.im = im;
(8)	}
(9)	public Complex() {
(10)		this.re = 0;
(11)		this.im = 0;
(12)	}
(13)	
(14)	public void setRe(double re) {
(15)		this.re = re;
(16)	}
(17)	public void setIm(double im) {
(18)		this.im = im;
(19)	}
(20)	public double getIm() {
(21)		return im;
(22)	}
(23)	public double getRe() {
(24)		return re;
(25)	}
(26)	public double modulus(Complex c1) {
(27)		return Math.sqrt(Math.pow(c1.getRe(), 2) + Math.pow(c1.getIm(), 2));
(28)	}
(29)	public Complex add(Complex c1, Complex c2) {
(30)		return new Complex(
(31)			c1.getRe() + c2.getRe(),
(32)			c1.getIm() + c2.getIm());
(33)	}
(34)	public Complex mult(Complex c1, Complex c2) {
(35)		return new Complex(
(36)			c1.getRe() * c2.getRe() - c1.getIm() * c2.getIm(),
(37)			c1.getRe() * c2.getIm() + c1.getIm() * c2.getRe());
(38)	}
(39)	public Complex div(Complex c1, Complex c2) {
(40)		double div = Math.pow(c2.getRe(), 2) + Math.pow(c2.getIm(), 2);
(41)		return new Complex(
(42)			(c1.getRe() * c2.getRe() + c1.getIm() * c2.getIm()) / div,
(43)			(c1.getIm() * c2.getRe() - c1.getRe() * c2.getIm()) / div);
(44)	}
(45)	public Complex pow(Complex c1, int n){
(46)		if (n==0) {
(47)			return new Complex(1,0);
(48)		}
(49)		Complex result = c1;
(50)		for (int i=1;i<n;i++){
(51)			result = result.mult(c1, c1);
(52)		}
(53)		return result;
(54)	}
(55)	public String toString() {
(56)		String result = new String();
(57)		result += re;
(58)		if (im < 0) {
(59)			result += "-";
(60)		} else {
(61)			result += "+";
(62)		}
(63)		result += "i" + Math.abs(im);
(64)		return result;
(65)	}
(66)}


Beispiel 125 zeigt die Implementierung der Klasse Complex deren Methoden als Web Service angeboten werden.
Augenscheinlich unterschiedet sich die Implementierung als Web Service nicht von der, die für die statische lokale Bereitstellung leistenden.
Bei der Umsetzung ist jedoch darauf zu achten, auf this-Verweise in Methodenrümpfen zu verzichten, da kein Objektkontext durch das SOAP-Protokoll mitversandt wird. Als pragmatisches Hilfsmittel zur Einhaltung dieser Einschränkung bietet es sich an die als Dienst bereitzustellenden Methoden mit dem Schlüsselwort static zu versehen.
Zusätzlich ist auf die Definition eines parameterlosen Vorgabekonstruktors zu achten, da dieser serverseitig zur durch das Framework zur Objekterzeugung herangezogen wird.

Die serverseitige Bereitstellung des Dienstes kann im Rahmen des Axis-Frameworks auf zwei Arten geschehen. Zum einen durch Bereitstellung des Quellcodes aus Beispiel 125 in einem dafür gesondert vorgesehen Serververzeichnis (typischerweise ../tomcat/webapps/axis). Zusätzlich ist die Datei mit der Extension jws (statt dem üblichen java) zu versehen. Zum Aufrufzeitpunkt wird der Quellcode durch das Axis-Framework für den Aufrufer transparent übersetzt und zur Ausführung gebracht.
Andererseits sieht das Framework die Möglichkeit der Ablage von vorübersetztem Java-Code vor. Dieser in der Axis-Terminologie als Web Service Deployment bezeichnete Vorgang gestattet dem Anwender weiterrechenden Einfluß auf Umstände der Dienstbereitstellung als die zuvor gezeigte Vorgehensweise.

Notwendige Voraussetzung des Deploymentvorganges ist die Bereitstellung einer separaten Konfigurationsdatei, dem sog. Deployment-Deskriptor unter zwingend vorgegebenen dem Dateinamen deploy.wsdd. Beispiel 126 zeigt eine solche Konfigurationsdatei für den Beispieldienst.

Beispiel 6: Deploymentdeskriptor des Beispieldienstes
Beispiel 126: Deploymentdeskriptor des Beispieldienstes
(1)<deployment
(2)	xmlns="http://xml.apache.org/axis/wsdd/"
(3)	xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
(4)   <service name="ComplexCalc" style="RPC">
(5)   	<parameter name="className" value="Complex"/>
(6)      <parameter name="allowedMethods" value="add mult modulus div pow"/>
(7)      <beanMapping
(8)        	qname="myNS:Complex"
(9)        	xmlns:myNS="urn:Complex"
(10)        	languageSpecificType="java:Complex"/>
(11)    </service>
(12)</deployment>


Innerhalb der Konfigurationsdatei werden Aussagen über das Interaktionsmuster, welches der Kommunikation mit dem Dienst zugrunde liegt. Im Beispiel wird durch die Belegung des Attributs style mit dem Wert RPC synchrone Kommunikation im Stile entfernter Methodenaufrufe gewählt.
Zusätzlich kann ein vom Namen des Compilats abweichender Dienstname frei festgelegt werden (im Beispiel ComplexCalc als Belegung des Attributs name des service-Elements).
Innerhalb der Kindelemente des Elements service wird die dienstimplementierende Klasse identifiziert (parameter-Element dessen name-Attribut den Wert className trägt, das zugehörige value-Attribut desselben Elements enthält dann den vollqualifizierten Klassennamen) sowie die per SOAP zugreifbaren Methoden mit separierenden Leerzeichen gemäß XML-Konvention aufgelistet (im Beispiel add mult modulus div pow).
Hierdurch eröffnet die Konfiguration des Webdienstes durch den Deploymentdeskriptor bereits einen Eingriffspunkt, der bei der reinen serverseitigen Ablage des Quellcodes, mit automatischer Freigabe aller öffentlich zugänglichen Methoden, nicht bestand.
Ferner können vermöge des Elements beanMapping anwenderdefinierte strukturierte Datentypen, die als Java-Bean-konforme Klasse umgesetzt sind definiert werden. Im Beispiel ist dies die Klasse zur Implementierung der komplexen Zahl.

Die Installation und Konfiguration (Deployment) des Web Service geschieht durch Aufruf des Administrationswerkeuges java org.apache.axis.client.AdminClient deploy.wsdd.
Zusätzlich ist die Dienstklasse im Verzeichnis .../tomcat/webapps/axis/WEB-INF/classes abzulegen.

Implementierung des Web Service Aufrufers:

Beispiel 7: Aufruf des Beispielwebdiensts
Beispiel 127: Aufruf des Beispielwebdiensts
(1)import java.rmi.RemoteException;
(2)import javax.xml.namespace.QName;
(3)import javax.xml.rpc.ParameterMode;
(4)import javax.xml.rpc.encoding.XMLType;
(5)import org.apache.axis.client.Call;
(6)import org.apache.axis.client.Service;
(7)import org.apache.axis.encoding.ser.BeanSerializerFactory;
(8)import org.apache.axis.encoding.ser.BeanDeserializerFactory;
(9)
(10)public class callService {
(11)	public static void main(String[] args) {
(12)		Call call = new Call( new Service() );
(13)
(14)		QName qn = new QName("urn:Complex","Complex");
(15)
(16)		call.setTargetEndpointAddress("http://10.0.0.1:8080/axis/services/ComplexCalc");
(17)		call.setOperationName("pow");
(18)		call.registerTypeMapping(Complex.class, qn,
(19)					  new BeanSerializerFactory(Complex.class, qn),
(20)					  new BeanDeserializerFactory(Complex.class, qn));
(21)
(22)		call.addParameter("c1", qn, ParameterMode.IN);
(23)		call.addParameter("n", XMLType.XSD_INT, ParameterMode.IN);
(24) 		Object[] param = new Object[2];
(25)		param[0] = new Complex(2,3);
(26)		param[1] = new Integer(3);
(27)
(28)		call.setReturnType( qn );
(29)
(30)		try {
(31)			Complex result = (Complex) call.invoke(param);
(32)			System.out.println("result=" + result);
(33)		} catch (RemoteException re) {
(34)			re.printStackTrace();
(35)		}
(36)	}
(37)}


Beispiel 127 zeigt die Implementierung eines Aufrufs des Beispielwebdienstes.
Zentrales Objekt des Aufrufs eines Web Service ist die Klasse Call. Sie kapselt die gesamten zur Kommunikation notwendigen Daten und übernimmt den synchronen Aufruf des entfernten Dienstes. Zur Verwaltung von Verbindungsdaten, die für verschieden Einzelaufrufe desselben Dienstes gleichermaßen Verwendung finden können diese zusätzlich durch einen Service repräsentiert werden. Im Beispiel wird hierauf jedoch aus Übersichtlichkeitsgründen verzichtet und alle alle Einstellungen direkt für das Call-Objekt vorgenommen.
Zu diesen Einstellungen zählt die dargestellte Angabe des Service Endpunktes, derjenigen Adresse, die konform zum gewählten Übertragungsprotkoll (im Beispiel ist dies HTTP) die physische Übergabestelle des SOAP-Aufrufs an den Web Service identifiziert.
Daher ist bei Änderung der Dienstbereitstellung, etwa durch Verlagerung auf einen anderen Server oder auch die sich aus dem oben gezeigten geänderten Deployment ergebende Endpunktadresse, lediglich der Parameter der Methode setTargetEndpointAddress geeignet anzupassen.

Zusätzlich zur Angabe der aufzurufenden Operation innerhalb des angesprochenen Dienstes, durch die Methode setOperationName erfolgt durch addParameter die Definition der Übergabeparameter des Dienstes.
Hierbei muß jeder Übergabeparameter in Name, Typ und Übergabeart spezifiziert werden. Im Beispiel sind dies die beiden Parameter c1 und n, die als Eingabe (d.h. nur zum lesenden Zugriff) der Methode pow dienen.
Diese Methode implementiert die Potenzierung komplexer Zahlen durch fortwährende Multiplikation. Ihre Signatur erfordert daher die Übergabe der komplexen Basis sowie des ganzzahligen Exponenten.

Zur Übertragung der speicherresidenten Wertdarstellung ordnet das Axis-Framework den Java-Primtivdatentypen und einigen ausgewählten als Klasse realisierten Datentypen eindeutige Abbildungen in die in XML-Schema definierten Datentypen zu.
Die Reihenfolge der Aufrufe der addParameter-Methode muß der Auftrittsreihenfolge in der Signatur des aufzurufenden Dienstes entsprechen, um die Kompatibilität zur Programmiersprachen, die ausschließlich über Stellungsparameter verfügen zu wahren.
Tabelle 31 stellt die durch das Axis-Framework Typäquivalenzen zusammen:

Tabelle  31: Abbildung der Java-Datentypen auf XML-Schema
Tabelle 31: Abbildung der Java-Datentypen auf XML-Schema
Java
XML-Schema
Bemerkung
byte[]
Beide Darstellungsweisen sind gleichwertig möglich.
boolean
byte
double
float
int
long
javax.xml.namespace.QName
Diese Javaklasse ist Bestandteil der API-Erweiterung für XML, die separat bezogen werden muß.
short


Bei der zu übergebenden komplexen Zahl handelt es sich um eine anwenderdefinierte Klasse, die einen neuen Java-Typ etabliert für den (naturgemäß) keine Entsprechung in XML-Schema zur Verfügung steht.
Aus diesem Grund muß auf Seiten des Aufrufers und des aufgerufenen Dienstes eine eigene Abbildungsvorschrift für die Erzeugung der SOAP-Darstellung bereitgestellt werden.

Durch die Axis-Serviceausführungsumgebung kann automatisiert eine solche Abbildung erzeugt werden, sofern der anwenderdefinierte Typ (d.h. die implementierende Klasse) gemäß der Java-Beans-Programmierkonvention umgesetzt ist. Diese ist eingehalten, sobald für jedes datenhaltende Attribut eine get- und set-Methode umgesetzt wird. Hintergrund dieses Vorgehens ist die Möglichkeit der Abfrage aller objektinternen Datenfelder durch Nutzung der Java-Reflection-API.
Die hierfür notwendige Zuordnung zwischen neuem Java- und XML-Typ geschieht im durch Beispiel 126 dargestellten Deploymentdeskriptor ab Zeile sieben. Dort gibt das Attribut qname den Namen des XML-Typs und languageSpecificType den Namen der implementierenden Java-Klasse (Complex) an.

Entsprechend vollzieht der Dienstaufrufer die Typabbildung im Code nach. Hierzu muß ihm der gewählte Name des neuen XML-Typen bekannt sein (im Beispiel: Complex im Namensraum urn:Complex). Durch den Aufruf der Methode registerTypeMapping gibt er dem Framework die Implementierungen der beiden Abbildungsrichtungen (Java-Hauptspeicherobjekte in SOAP bzw. SOAP zu Hauptspeicherobjekten) bekannt. Das Beispiel verwendet hierzu die im Axis-Framework mitgelieferten Klassen BeanSerializerFactory und BeanDeserializerFactory welche das Gewünschte auf Basis einer als Java-Bean codierten Klasse leisten.

Die Festlegung der tatsächlichen Übergabewerte erfolgt im Beispiel durch Erzeugung eines Arrays zur Aufnahme von Object-typisierten Elementen in die die zuvor hinsichtlich ihres Typs definierten Aktualparameter eingefügt werden.
Aufgrund der Einschränkung der Programmiersprache Java (bis zur Version 1.4), die Ausprägungen von Primitivtypen nicht als Objekte behandeln kann, erfolgt im Beispiel die Kapselung des int-Wertes für n durch ein Objekt der Klasse Integer.

Für die Definition des Typs des erwarteten Rückgabewertes gelten dieselben Gesetztmäßigkeiten hinsichtlich Bekanntmachung und Zugriffsabwicklung. Die Definition des erwarteten Rückgabetyps erfolgt durch Aufruf der Methode setReturnType.

Der synchrone Aufruf des entfernten Dienstes wird dann durch die Methode invoke des erzeugten und entsprechend parametrisierten Call-Objektes vollzogen.
Dieser Aufruf ist blockierend und läßt den Aufrufer bis zum Eintreffen des berechneten Ergebnisses warten.

Die Rückgabe wird, trotz der Definition des spezielleren Rückgabetyps Complex generell als Object-Ausprägung geliefert um eine strikt typprüfbare Signatur der Methode invoke zu erhalten. Daher muß das durch den Web Service gelieferte Resultat geeignet, d.h. konform zur durch setReturnType getroffenen Festlegung, typgewandelt werden.

Beispiel 128 zeigt den SOAP-Datenverkehr beim Aufruf des Dienstes zur Berechnung der Potenz einer komplexen Zahl. Aufgrund des derzeitigen Entwicklungsstandes des Axis-Frameworks weicht der Leitungsmittschnitt von der zu Eingang dieses Kapitels vorgestellten SOAP-Struktur des W3C-Standards ab. Gegenwärtig (d.h. zum Zeitpunkt der Verfügbarkeit der Version 1.1) unterstützt das Framework nur eine Untermenge des neuen Standards und codiert die XML-Nachrichten noch nach dem Stand der Vorgängerspezifikation.

Beispiel 8: SOAP-Nachricht zum Aufruf des Beispieldienstes
Beispiel 128: SOAP-Nachricht zum Aufruf des Beispieldienstes
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<soapenv:Envelope
(3)	xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
(4)	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
(5)	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
(6) 	<soapenv:Body>
(7)  		<pow soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
(8)   		<c1 href="#id0"/>
(9)   		<n xsi:type="xsd:int">3</n>
(10)  		</pow>
(11)  		<multiRef
(12)  			id="id0"
(13)  			soapenc:root="0"
(14)  			soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
(15)  			xsi:type="ns1:Complex"
(16)  			xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
(17)  			xmlns:ns1="urn:Complex">
(18)   		<im xsi:type="xsd:double">3.0</im>
(19)   		<re xsi:type="xsd:double">2.0</re>
(20)  		</multiRef>
(21) 	</soapenv:Body>
(22)</soapenv:Envelope>


Im Code des Beispiels gut zu sehen ist die Darstellung der beiden Übergabeparameter c1 und n für die Basis der Potenzierung und den ganzzahligen Exponenten. Für n wird die in Tabelle 128 Abbildung in den äquivalenten Typen int aus XML-Schema durchgeführt. Zusätzlich überträgt die durch Axis gewählte Codierung die Typisierung explizit mit (Attribut xsi:type="xsd:int") wodurch die Typabbildung offenbar wird.
Für den nicht direkt nach XML-Schema transformierbaren strukturierten (Java-)Datentypen Complex wird durch den Serialisierungsmechanismus ein eigenes mit multiRef bezeichnetes und durch das Attribut id identifiziertes Element erzeugt. Dieses Vorgehen entspricht der durch die SOAP-Spezifikation vorgesehenen Serialisierungs allgemeiner Graphen, welche die speicherresidenten Datenobjekte als Knoten interpretiert und hierfür wiederverwendbare (der Name des Elements deutet dies an) Elemente erzeugt. Die tatsächliche Wiederverwendung innerhalb des SOAP-Stromes findet durch Mehrfachnennung des im id-Attribut festgelegten identifizierenden Wertes im href-Attribut eines Verweiselementes statt.
Im Beispiel wird die Berechnungsbasis als ein solches multiRef-Element ausgedrückt, welches die Wertbelegungen der durch get-Methoden zugänglichen Javafelder (im und re) enthält.
Das den Übergabeparameter c1 repräsentierende XML-Element enthält daher lediglich im href-Attribut einen Verweis auf die multiRef-Struktur.

Beispiel 129 zeigt den für die Übermittlung des Dienstergebnisses übertragenen SOAP-Datenverkehr.
Auch er weicht, aufgrund der Konformität zur älteren SOAP-Spezifikationsversion, geringfügig vom aktuellen Standard ab.

Beispiel 9: SOAP-Nachricht zur Übermittlung des Berechnungsergebnisses des Beispieldienstes
Beispiel 129: SOAP-Nachricht zur Übermittlung des Berechnungsergebnisses des Beispieldienstes
(1)<?xml version="1.0" encoding="UTF-8"?>
(2)<soapenv:Envelope
(3)	xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
(4)	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
(5)	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
(6) 	<soapenv:Body>
(7)  		<powResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
(8)   	<powReturn href="#id0"/>
(9)  	</powResponse>
(10)  	<multiRef
(11)  		id="id0"
(12)  		soapenc:root="0"
(13)  		soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
(14)  		xsi:type="ns1:Complex"
(15)  		xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
(16)  		xmlns:ns1="urn:Complex">
(17)   	<im xsi:type="xsd:double">12.0</im>
(18)   	<re xsi:type="xsd:double">-5.0</re>
(19)  	</multiRef>
(20) 	</soapenv:Body>
(21)</soapenv:Envelope>


Wie bereits beim Aufruf realisiert wird die XML-Darstellung des strukturierten Datentyps Complex, der hier als Rückgabetyp dient, durch Nutzung der allgemeinen Graphenserialisierung erzeugt.

WSDL

Die Grundidee der Web Services fordert nicht zwingend die Darstellung der Dienstschnittstellen für Dritte, wie dies beispielsweise Verteilungsarchitekturen wie CORBA und DCOM zwingend als Teil des Entwicklungszyklus vorgeben. Dennoch erweist es sich auch für Web Services sinnvoll die Schnittstellenbeschreibungen in einem maschinenlesbaren Format bereitzustellen um Werkzeugen die automatisierte Verarbeitung zu ermöglichen. Hierunter fallen beispielsweise Entwicklungsumgebungen, die aus Schnittstellenbeschreibungen erste Rohgerüste für die Abwicklung der Dienstaufrufe generieren können. Zusätzlich stellen formalisiert dokumentierte Schnittstellen einen wichtigen Bestandteil der Dokumentation eines Softwaresystems dar.
Zur Schnittstellendokumentation von Web Services etabliert sich gegenwärtig der Standard der Web Service Description Language, der durch eine Arbeitsgruppe des World Wide Web Konsortiums vorangetrieben wird.

Eine WSDL-Beschreibung selbst ist eine XML-Datei, WSDL mithin als XML-Schema-basiertes XML-Vokabular realisiert und zerfällt in sechs Teile:

  1. Service: Zur allgemeinen Beschreibung des angebotenen Dienstes
  2. Operations: Zur Beschreibung der angebotenen Operationen
  3. Messages: Zur Beschreibung Signatur der einzelnen Nachrichten (Aufrufe und Antworten)
  4. PortTypes: Zur Verknüpfung von Operations und Messages
  5. Bindings: Zur Verknüpfung einer Operation mit einem Transportprotkoll
  6. Types: Zur Definition anwenderdefinierter Übergabe- und Rückgabetypen

Die Angaben zur Struktur der anwenderdefinierten Typen ist optional und muß nur im Falle der Existenz solcher Typen erfolgen.

Das Beispiel 130 zeigt die vollständige WSDL-Dienstbeschreibung des aus der Fallstudie bekannten Dienstes:

Beispiel 10: WSDL-Beschreibung des Beispieldienstes
Beispiel 130: WSDL-Beschreibung des Beispieldienstes
(1)<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://10.0.0.1:8080/axis/services/Complex" xmlns:intf="http://10.0.0.1:8080/axis/services/Complex" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="urn:Complex" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://10.0.0.1:8080/axis/services/Complex">
(2)	<wsdl:types>
(3)		<schema targetNamespace="urn:Complex" xmlns="http://www.w3.org/2001/XMLSchema">
(4)			<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
(5)			<complexType name="Complex">
(6)				<sequence>
(7)					<element name="im" type="xsd:double"/>
(8)					<element name="re" type="xsd:double"/>
(9)				</sequence>
(10)			</complexType>
(11)		</schema>
(12)	</wsdl:types>
(13)	<wsdl:message name="addResponse">
(14)		<wsdl:part name="addReturn" type="tns1:Complex"/>
(15)	</wsdl:message>
(16)	<wsdl:message name="divRequest">
(17)		<wsdl:part name="c1" type="tns1:Complex"/>
(18)		<wsdl:part name="c2" type="tns1:Complex"/>
(19)	</wsdl:message>
(20)	<wsdl:message name="modulusRequest">
(21)		<wsdl:part name="c1" type="tns1:Complex"/>
(22)	</wsdl:message>
(23)	<wsdl:message name="divResponse">
(24)		<wsdl:part name="divReturn" type="tns1:Complex"/>
(25)	</wsdl:message>
(26)	<wsdl:message name="multResponse">
(27)		<wsdl:part name="multReturn" type="tns1:Complex"/>
(28)	</wsdl:message>
(29)	<wsdl:message name="powResponse">
(30)		<wsdl:part name="powReturn" type="tns1:Complex"/>
(31)	</wsdl:message>
(32)	<wsdl:message name="addRequest">
(33)		<wsdl:part name="c1" type="tns1:Complex"/>
(34)		<wsdl:part name="c2" type="tns1:Complex"/>
(35)	</wsdl:message>
(36)	<wsdl:message name="modulusResponse">
(37)		<wsdl:part name="modulusReturn" type="xsd:double"/>
(38)	</wsdl:message>
(39)	<wsdl:message name="powRequest">
(40)		<wsdl:part name="c1" type="tns1:Complex"/>
(41)		<wsdl:part name="n" type="xsd:int"/>
(42)	</wsdl:message>
(43)	<wsdl:message name="multRequest">
(44)		<wsdl:part name="c1" type="tns1:Complex"/>
(45)		<wsdl:part name="c2" type="tns1:Complex"/>
(46)	</wsdl:message>
(47)	<wsdl:portType name="Complex">
(48)		<wsdl:operation name="pow" parameterOrder="c1 n">
(49)			<wsdl:input name="powRequest" message="impl:powRequest"/>
(50)			<wsdl:output name="powResponse" message="impl:powResponse"/>
(51)		</wsdl:operation>
(52)		<wsdl:operation name="add" parameterOrder="c1 c2">
(53)			<wsdl:input name="addRequest" message="impl:addRequest"/>
(54)			<wsdl:output name="addResponse" message="impl:addResponse"/>
(55)		</wsdl:operation>
(56)		<wsdl:operation name="mult" parameterOrder="c1 c2">
(57)			<wsdl:input name="multRequest" message="impl:multRequest"/>
(58)			<wsdl:output name="multResponse" message="impl:multResponse"/>
(59)		</wsdl:operation>
(60)		<wsdl:operation name="modulus" parameterOrder="c1">
(61)			<wsdl:input name="modulusRequest" message="impl:modulusRequest"/>
(62)			<wsdl:output name="modulusResponse" message="impl:modulusResponse"/>
(63)		</wsdl:operation>
(64)		<wsdl:operation name="div" parameterOrder="c1 c2">
(65)			<wsdl:input name="divRequest" message="impl:divRequest"/>
(66)			<wsdl:output name="divResponse" message="impl:divResponse"/>
(67)		</wsdl:operation>
(68)	</wsdl:portType>
(69)	<wsdl:binding name="ComplexSoapBinding" type="impl:Complex">
(70)		<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
(71)		<wsdl:operation name="pow">
(72)			<wsdlsoap:operation/>
(73)			<wsdl:input>
(74)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(75)			</wsdl:input>
(76)			<wsdl:output>
(77)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(78)			</wsdl:output>
(79)		</wsdl:operation>
(80)		<wsdl:operation name="add">
(81)			<wsdlsoap:operation/>
(82)			<wsdl:input>
(83)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(84)			</wsdl:input>
(85)			<wsdl:output>
(86)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(87)			</wsdl:output>
(88)		</wsdl:operation>
(89)		<wsdl:operation name="mult">
(90)			<wsdlsoap:operation/>
(91)			<wsdl:input>
(92)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(93)			</wsdl:input>
(94)			<wsdl:output>
(95)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(96)			</wsdl:output>
(97)		</wsdl:operation>
(98)		<wsdl:operation name="modulus">
(99)			<wsdlsoap:operation/>
(100)			<wsdl:input>
(101)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(102)			</wsdl:input>
(103)			<wsdl:output>
(104)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(105)			</wsdl:output>
(106)		</wsdl:operation>
(107)		<wsdl:operation name="div">
(108)			<wsdlsoap:operation/>
(109)			<wsdl:input>
(110)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(111)			</wsdl:input>
(112)			<wsdl:output>
(113)				<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.0.0.1:8080/axis/services/Complex"/>
(114)			</wsdl:output>
(115)		</wsdl:operation>
(116)	</wsdl:binding>
(117)	<wsdl:service name="ComplexService">
(118)		<wsdl:port name="Complex" binding="impl:ComplexSoapBinding">
(119)			<wsdlsoap:address location="http://10.0.0.1:8080/axis/services/Complex"/>
(120)		</wsdl:port>
(121)	</wsdl:service>
(122)</wsdl:definitions>


Das Beispiel spiegelt im Service-Element die bereits durch den Deploymentdeskriptor getroffenen Festlegungen wieder und macht sie so dem (potentiellen) Dienstnutzer zugänglich. So enthält das Attribut name mit dem Wert ComplexService den gewählten Namen des Dienstes. Zusätzlich der als Kindelement realisierte address-Eintrag unter location die Adresse des SOAP-Endpunktes wieder welche SOAP-Botschaften zum Dienstaufruf entgegennimmt.
Da derselbe Dienst durch verschiedene Endpunkte zur Verfügung gestellt werden kann, ist das mehrfache Auftreten von address-Element zugelassen. Aus Gründen der Eindeutigkeit und Zuordnung des Endpunktes zum jeweils unterstützten Transportprotokoll ist jedes address-Element durch ein port-Element umschlossen welches auf das definierte Protokoll verweist.

Jedes Operation-Element definiert die zum Aufruf zu übermittelnden Parameter hinsichtlich Reihenfolge und referenziert die eine Interaktion konstituierenden Interaktionsschritte.
Im Beispiel legt die Operation pow (die Benennung wird durch das name-Attribut festgelegt) fest, daß die beiden Parameter c1 und n benötigt werden. Zusätzlich erfolgt durch das Element input eine Referenz auf die Eingabenachricht bzw. output auf die Ausgabenachricht die zur Initiierung der Operation bzw. nach deren Ende versandt werden.

Innerhalb des Message-Elements werden die Übergabe Parameter inhaltlich hinsichtlich Typ und Name ausdefiniert.
Für die Nachricht powRequest (Aufruf der Methode pow) werden daher c1 vom Typ eigendefinierten Typ Complex sowie n vom Standardtyp int genannt.

Durch das WSDL-Element PortType erfolgt die Aggregation der zuvor definierten Operationen, deren Nachrichten, an den in der Service-Definition genannten Endpunkt.

Die technischen Details wie gewähltes Encodierungsschema und genutzter Namensraum werden im Rahmen des Binding-Elements für jeden Nichtstandardtypen --- im Beispiel ist dies Complex --- definiert.

Die zur Erzeugung der über die Netzwerkleitung zu transportierenden XML-Darstellung dieser Nichtstandardtypen wird durch ein XML-Schemafragment beschrieben, welches als Kindelement des WSDL-Elements Types abgelegt ist.

UDDI

Zwar bietet WSDL eine wertvolle Möglichkeit zur Beschreibung der technischen Schnittstellencharakteristika eines Web Service, jedoch bleiben andere Fragestellungen --- etwa die nach der Natur und menschenlesbaren Beschreibung eines Dienstes oder seinen Nutzungs- und Abrechnungsbedingungen --- durch diesen Standard vollkommen offen. Überdies enthält das offizielle Spezifikationsdokument keinerlei Aussagen über einen präferierten oder auch nur sinnvollen Bereitstellungsort der WSDL-Beschreibungen.
Einen Ansatz zur Antwort auf diese Fragestellungen versucht der im Rahmen des OASIS-Standardisierungsprozeß vorangetriebene Verzeichnisdienst Universal Service Description, Discovery and Integration zu liefern.

Dieses, selbst als SOAP-basierter Web-Dienst angebotene, Verzeichnisdienst stellt eine Verwaltungsstruktur zur Ablage von WSDL-Beschreibungen und anderer dienstbezogener deskriptiver Metadaten bereit die durch eine definierte Schnittstelle abgefragt werden kann.

Die Grundprimitive des UDDI-Dienstes sind:

Ziel der Business Entity-Struktur ist es telephonbuchartig beschreibende Metadaten zum Dienstanbieter, wie Firmenname und Erreichbarkeitsdaten in einer alphabetisch sortierten Struktur anzubieten.

Jedem Business Entity-Eintrag können mehrere Business Services zugeordnet sein, welche die angebotenen Web Services repräsentieren.

Jedes tModel (Abkürzung für technical model) kann eine WSDL-Beschreibung oder beliebige durch den Anwender festlegbare dienstbezogene deskriptive Inhalte aufnehmen.
Insbesondere kann ein tModel auch Kategorisierungen eines Dienstes, etwa die Zuordnung zu einer Dienstfamilie, die Herstellung eines bestimmten Typ-Kontexts wie Erbringungsort des Dienstes, aufnehmen.

Alle tModels eines Dienstes werden mit diesem durch BindingTemplate-Elemente verbunden.

Die Interaktion mit einem UDDI-Verzeichnisdienst kann SOAP-basiert oder durch manuelle Erfassung der abzulegenden Daten über eine Webseite erfolgen.
Ziel dieser Interaktion ist zumeist einer der global angebotenen UDDI-Verzeichnisdienste, die gegenwärtig innerhalb eines Tages für die vollständige Inhaltsreplizierung sorgen.

Aufgrund immernoch offener Sicherheitsfragestellungen und der als ungelöst anzusehenden Abrechnungsproblematik liegen jedoch in den aktuell zugänglichen UDDI-Diensten kaum kommerzielle Dienstangebote vor, sondern überwiegend Testeinträge.

Web-Referenzen 1: Weiterführende Links
Web-Referenzen 21: Weiterführende Links


3.6   XML und Datenbanken

Seit dem Aufkommen XMLs als universellem Format zur Darstellung beliebiger Daten wird die Fragestellung nach einer adäquaten Speicherung von XML-codierten Daten diskutiert. Die Anforderungen beschränken sich hierbei nicht auf die Betrachtung der reinen Ablage im Dateisystem oder der Verwaltung durch ein Datenbankmanagementsystem, sondern beziehen auch Aspekte der Performance der lesenden und schreiben Operationen auf diesen Daten sowie der Formulierung flexibler Anfragen ein. Gleichzeitig ist jedoch die aufgeworfene Frage nach der sinnvoll(st)en Repräsentation XML-artiger semistrukturierter Daten innerhalb einer Persistenzschicht noch nicht eindeutig und letztgültig beantwortet worden, sofern sie dies überhaupt ist.

Generell bieten sich zur Ablage von XML drei Klassen von Speicherungsmechanismen an, die gegenwärtig alle in der Praxis verwendet werden:

  1. Ablage als unstrukturierter (Text-artiger oder binärer) Datenstrom im Datei- oder einem Datenbanksystem.
  2. Transformation in logische Datenbankstrukturen.
  3. Speicherung in einem „nativen“ XML-Datenbanksystem.

Diese drei Klassen stellen jedoch nur eine erste taugliche Grobeinteilung dar und sind intern durchaus unterstrukturiert und teilweise höchst fragmentiert.

Speicherung von XML-Inhalten als unstrukturierte Datenströme

Grundidee und Konzepte
Naheliegendste Form der Speicherung von XML-Inhalten ist zweifellos die Ablage des XML-Stromes, der ohnehin zumeist als Datei vorliegt, in einem klassischen Dateisystem (z.B. ext2, NTFS, FAT).
In dieselbe Klasse fällt auch die Speicherung als unstrukturierter Inhalt in einem Datenbankmanagementsystem. Hierzu werden zumeist Datentypen wie BLOB (binary large object) oder CLOB (character large object) eingesetzt, die zur Aufnahme großer Mengen binärer oder textartiger Daten geeignet sind.

Beispiel
Die Speicherung im Dateisystem erfolgt (trivialerweise) in Dateien, d.h. die Erzeugung der XML-Daten beschränkt sich auf die Anlage, Benennung und Katalogszuordnung der Datei. Die XML-Daten werden aus einem Applikation mittels einer XML-Programmierschnittstelle direkt geschrieben oder durch per Netzwerk erhalten.

Die Speicherung in einem DBMS erfordert die Definition einer entsprechenden logischen Struktur zur Aufnahme der XML-Daten, die datenbankintern auf physische Speicherstrukturen abgebildet wird.
131 zeigt eine Implementierung für das relationale Datenbankmanagementsystem MySQL, die eine per Kommandozeilenargument übergebene Datei im Feld DATA der Datenbanktabelle XML ablegt. Das Feld mit LONGTEXT typisiert, was im verwendenten DBMS die Aufnahme von 232-1 Zeichen gestattet. Physisch wird LONGTEXT auf einen BLOB mit case-insensitiver Suchmöglichkeit abgebildet.

Beispiel 25: Unstrukturierte Speicherung von XML-Dokumenten in einer Datenbank
Beispiel 131: Unstrukturierte Speicherung von XML-Dokumenten in einer Datenbank
(1)import java.io.File;
(2)import java.io.FileInputStream;
(3)import java.io.IOException;
(4)import java.sql.Connection;
(5)import java.sql.DriverManager;
(6)import java.sql.PreparedStatement;
(7)import java.sql.SQLException;
(8)import java.sql.Statement;
(9)
(10)public class XML2DB {
(11)	public static void main(String[] args)
(12)	throws ClassNotFoundException, SQLException, IOException {
(13)		Class.forName("com.mysql.jdbc.Driver");
(14)		Connection con =
(15)				(Connection) DriverManager.getConnection(
(16)					"jdbc:mysql://10.0.0.1/XMLunstructured/",
(17)					"mario",
(18)					"thePassword");
(19)
(20)		Statement stmt = con.createStatement();
(21)		stmt.executeUpdate("CREATE TABLE IF NOT EXISTS XML(Data LONGTEXT);");
(22)
(23)		File file = new File(args[0]);
(24)		FileInputStream fis = new FileInputStream(args[0]);
(25)		PreparedStatement pstmt =
(26)			con.prepareStatement("INSERT INTO XML VALUES(?)");
(27)		pstmt.setBinaryStream(1, fis, (int) file.length());
(28)		pstmt.executeUpdate();
(29)		fis.close();
(30)	}
(31)}
Download des Beispiels


Zugriffe auf Inhalte (beispielsweise Extraktion eines Teilbaumes per XPath) des abgelegten XML-Dokumentes können datenbankseitig nicht direkt unterstützt werden, da das gesamte Dokument als (große) Zeichenkette interpretiert wird. Alle gewünschten Zugriffe müssen daher auf die vorhandenen Funktionen zur Auswertung von Zeichenketten abgebildet werden. Teilweise stellen die Datenankhersteller angepaßte Module zum Zugriff auf Volltextinformation zur Verfügung, die diesen Schritt vollziehen.

Das Auslesen des in der Datenbank abgelegten Dokuments vollzieht sich invers zur Ablage ebenfalls in Form von reinen Operationen zur Verarbeitung des gespeicherten Binärstroms, ohne Berücksichtigung seiner Natur als XML-Dokument. Beispiel 132 zeigt dies:

Beispiel 26: Auslesen eines unstrukturierte gespeicherten XML-Dokuments
Beispiel 132: Auslesen eines unstrukturierte gespeicherten XML-Dokuments
(1)import java.io.FileDescriptor;
(2)import java.io.FileOutputStream;
(3)import java.io.IOException;
(4)import java.sql.Connection;
(5)import java.sql.DriverManager;
(6)import java.sql.ResultSet;
(7)import java.sql.SQLException;
(8)import java.sql.Statement;
(9)
(10)public class DB2XML {
(11)
(12)	public static void main(String[] args)
(13)	throws ClassNotFoundException, SQLException, IOException {
(14)		Class.forName("com.mysql.jdbc.Driver");
(15)		Connection con  =
(16)			(Connection) DriverManager.getConnection(
(17)				"jdbc:mysql://10.0.0.1/XMLunstructured/",
(18)				"mario",
(19)				"thePassword");
(20)		Statement stmt = (Statement) con.createStatement();
(21)		ResultSet rs =
(22)			stmt.executeQuery(
(23)				"SELECT Data FROM XML;");
(24)
(25)		FileOutputStream fos = new FileOutputStream(FileDescriptor.out);
(26)		if (rs.next())
(27)			fos.write(rs.getBytes(1));
(28)		fos.close();
(29)	}
(30)}
Download des Beispiels


Diskussion der Vor- und Nachteile

Für das Konzept der unstrukturierten binären oder zeichenorientierten Ablage spricht die Verfügbarkeit seitens der bestehenden Datenbankmanagementsysteme, da die Einführung einer „XML-Unterstützung“ in dieser Form keinerlei Modifikationen am bestehenden System bedarf. Im selben Sinne können XML-Dokumente in Form von Textdateien durch bestehende Betriebssysteme verwaltet werden.
Gleichzeitig können die Lese- und Schreiboperationen in vergleichsweise großer Geschwindigkeit durchgeführt werden, da keine Abbildungen in interne Speicherstrukturen erfolgen muß.
Andererseits können XML-typische Zugriffsoperationen, durch die Lokatorsprache XPath oder die Anfragesprache XQuery für Dateien nur durch separate Lösungen und für Datenbankmanagementsysteme, nur durch Zeichenkettenverarbeitungsfunktionen oder darauf aufsetzende Module bereitgestellt werden. Im Allgemeinen müssen Zugriffsschritte, welche XML-Strukturen ausbeuten diese zunächst dynamisch zur Laufzeit im Hauptspeicher aus dem Zeichenstrom des Dokumentes re-generieren, was sich negativ auf die Ausführungszeit auswirkt.
Dieses mangelnde Wissen über internen Aufbau und Struktur eines XML-Dokuments erfordert zusätzliche Schritte zur Gewährleistung der Konsistenz der verwalteten Daten. So muß der Anwender Sorge dafür tragen, daß nur wohl-geformte XML-Dokumente als solche abgelegt werden, da weder das Dateisystem noch das DBMS für allgemeine Binärströme geeignete Validierungsfuntionen bereitstellen.

Abbildung von XML-Inhalten auf logische DB-Strukturen

Grundidee und Konzepte
Zur Behebung der formulierten Nachteile des naiven Speicherungsansatzes --- unter gleichzeitiger Erhaltung des Vorteils der Verfügbarkeit ohne Änderungen oder Erweiterungen an bestehenden Verwaltungssystemen vornehmen zu müssen --- bietet sich die Speicherung in eigens geschaffenen logischen Strukturen konform zu einem bestehenden logischen Modell an. Typischerweise wird hierzu eine generische oder dokumenttypsspezifische Abbildung der XML-Strukturen in das den verwaltbaren Datenbanken zugrundeliegende Modell definiert. Hierbei finden überwiegend relationale Systeme Einsatz, Objektorientiere oder Hierarchische sind hingegen nur selten anzutreffen.
Naturgemäß bedarf die Verfolgung dieses Ansatzes der Existenz eines Verwaltungssystems, welches die logischen Strukturen bereitstellt und verarbeitet. Aus diesem Grunde scheiden ausschließlich Datei-basierte Ansätze, die sich nicht zusätzlicher interpretierender Applikationen bedienen, welche die Semantik der verwalteten Strukturen kennen, aus.

Beispiel
Die Applikation der Beispiele 133 und 134 setzt eine bijektive Abbildung allgemeiner XML-Strukturen in logische Relationenstrukturen um.

Abbildung 58 zeigt einen Ausschnitt des konzeptuellen Schemas (es bedient sich der Notation des Semantically Enriched Extended Entity Relationship-Modells) welches der Bildung der notwendigen Relationenstrukturen zugrunde liegt.
Die Strukturen sind dabei so gehalten, daß sie für beliebige XML-Dokumente dienen können. Hierzu orientiert sich das Schema an den strukturellen und begrifflichen Gegebenheiten des XML Information Sets.

Konzeptuelles Schema des XML-Infosets (Ausschnitt)

Zur hierarchieunabhängigen Identifikation der einzelnen verwalteten Elemente wird ein Surrogatattribut (ID) eingeführt, welches einen automatisch erzeugten Schlüssel in Form eines zeit- und raumunabhängigen Identifikators enthält.
Mit den in der Abbildung dargestellten Strukturen können wohlgeformte XML-Dokumente die ausschließlich Elemente, Attribute und textuellen Elementinhalt umfassen verwaltet werden. Aus Gründen der Übersichtlichkeit sind weitere XML-Strukturprimitive weggelassen.
Durch die aus dem konzeptuellen Schema erzeugten Relationenstrukturen können Teile der strukturellen Anforderungen an die Wohlgeformtheit eines Dokuments automatisiert durch das verwendete DBMS geprüft werden. Hierzu zählt die Anforderung der eindeutigen Benennung von Attributen innerhalb eines Elements sowie die streng hierarchische Schachtelung der XML-Elemente.

Beispiel 133 zeigt die Implementierung zur Erzeugung der Relationenstrukturen sowie zu deren Befüllung mit den Inhalten eines per Kommandozeilenargument übergebenen XML-Dokuments.

Beispiel 27: Speichern eines XML-Dokuments in einer relationalen Datenbank
Beispiel 133: Speichern eines XML-Dokuments in einer relationalen Datenbank
(1)package de.jeckle.tinyXMLDB;
(2)
(3)import java.io.IOException;
(4)import java.sql.Connection;
(5)import java.sql.DriverManager;
(6)import java.sql.ResultSet;
(7)import java.sql.SQLException;
(8)import java.sql.Statement;
(9)import java.util.Stack;
(10)
(11)import javax.xml.parsers.ParserConfigurationException;
(12)import javax.xml.parsers.SAXParser;
(13)import javax.xml.parsers.SAXParserFactory;
(14)
(15)import org.doomdark.uuid.UUIDGenerator;
(16)import org.xml.sax.Attributes;
(17)import org.xml.sax.SAXException;
(18)import org.xml.sax.helpers.DefaultHandler;
(19)
(20)public class XML2DB extends DefaultHandler {
(21)	private Connection con = null;
(22)	private Stack elementStack;
(23)	private String inputFile;
(24)	private UUIDGenerator gen;
(25)
(26)	public static void main(String[] args)
(27)		throws
(28)			ParserConfigurationException,
(29)			SAXException,
(30)			IOException,
(31)			ClassNotFoundException,
(32)			SQLException {
(33)		XML2DB xml2db = new XML2DB();
(34)		xml2db.con = xml2db.connectDB();
(35)		for (int i = 0; i < args.length; i++) {
(36)			if (args[i].compareTo("-createDB") == 0) {
(37)				xml2db.createDB(xml2db.con);
(38)			}
(39)			if (args[i].compareTo("-store") == 0) {
(40)				xml2db.elementStack = new Stack();
(41)				xml2db.inputFile = args[i + 1];
(42)			}
(43)		}
(44)
(45)		xml2db.gen = UUIDGenerator.getInstance();
(46)
(47)		SAXParserFactory spf = SAXParserFactory.newInstance();
(48)		SAXParser sp = spf.newSAXParser();
(49)		System.out.print("storing document ...");
(50)		sp.parse(xml2db.inputFile, xml2db);
(51)		System.out.println("done");
(52)	}
(53)
(54)	private Connection connectDB()
(55)		throws ClassNotFoundException, SQLException {
(56)		Class.forName("com.mysql.jdbc.Driver");
(57)		return (Connection) DriverManager.getConnection(
(58)			"jdbc:mysql://10.0.0.1/XML/",
(59)			"mario",
(60)			"thePassword");
(61)	}
(62)
(63)	private void createDB(Connection con) throws SQLException {
(64)		System.out.print("creating database ...");
(65)		Statement stmt = con.createStatement();
(66)
(67)		stmt.executeUpdate(
(68)			"CREATE TABLE IF NOT EXISTS Element("
(69)				+ "ID VARCHAR(36) PRIMARY KEY,"
(70)				+ "Name VARCHAR(50) NOT NULL,"
(71)				+ "ParentElement VARCHAR(36),"
(72)				+ "SeqNo int);");
(73)		stmt.executeUpdate(
(74)			"ALTER TABLE Element ADD INDEX ParentIdx (ParentElement);");
(75)		stmt.executeUpdate(
(76)			"ALTER TABLE Element ADD CONSTRAINT ParentElementFK FOREIGN KEY (ParentElement) REFERENCES Element(ID);");
(77)
(78)		stmt.executeUpdate(
(79)			"CREATE TABLE IF NOT EXISTS Text("
(80)				+ "TextualContent Text NOT NULL,"
(81)				+ "ParentElement VARCHAR(36) NOT NULL,"
(82)				+ "SeqNo int NOT NULL,"
(83)				+ "PRIMARY KEY (SeqNo, ParentElement));");
(84)		stmt.executeUpdate(
(85)			"ALTER TABLE Text ADD INDEX ParentIdx (ParentElement);");
(86)		stmt.executeUpdate(
(87)			"ALTER TABLE Text ADD CONSTRAINT ParentElementFK FOREIGN KEY (ParentElement) REFERENCES Element(ID);");
(88)
(89)		stmt.executeUpdate(
(90)			"CREATE TABLE IF NOT EXISTS Attribute("
(91)				+ "Name VARCHAR(20) NOT NULL,"
(92)				+ "ParentElement VARCHAR(36) NOT NULL,"
(93)				+ "Value VARCHAR(50) NOT NULL,"
(94)				+ "PRIMARY KEY (Name, ParentElement));");
(95)		stmt.executeUpdate(
(96)			"ALTER TABLE Attribute ADD INDEX ParentIdx (ParentElement);");
(97)		stmt.executeUpdate(
(98)			"ALTER TABLE Attribute ADD CONSTRAINT ParentElementFK FOREIGN KEY (ParentElement) REFERENCES Element(ID);");
(99)
(100)		System.out.println("done");
(101)	}
(102)
(103)	public void startDocument() {
(104)		elementStack.push(null);
(105)	}
(106)
(107)	public void startElement(
(108)		String namespaceURI,
(109)		String localName,
(110)		String qName,
(111)		Attributes atts) {
(112)		String uuid = gen.generateTimeBasedUUID().toString();
(113)		String parentID = (String) elementStack.peek();
(114)
(115)		try {
(116)			Statement stmt = con.createStatement();
(117)			String st = null;
(118)			ResultSet rs =
(119)				stmt.executeQuery(
(120)					"(SELECT max(SeqNo) AS max FROM Element WHERE ParentElement=\""
(121)						+ parentID
(122)						+ "\")"
(123)						+ " UNION "
(124)						+ "(SELECT max(SeqNo) AS max FROM Text WHERE ParentElement=\""
(125)						+ parentID
(126)						+ "\")"
(127)						+ "ORDER BY 1 DESC;");
(128)			rs.first();
(129)			int childSeq = rs.getInt("max");
(130)
(131)			if (parentID == null) {
(132)				st =
(133)					"INSERT INTO Element (ID, Name, SeqNo) VALUES("
(134)						+ "\""
(135)						+ uuid
(136)						+ "\","
(137)						+ "\""
(138)						+ qName
(139)						+ "\","
(140)						+ ++childSeq
(141)						+ ");";
(142)			} else {
(143)				st =
(144)					"INSERT INTO Element (ID, Name, SeqNo, ParentElement) VALUES("
(145)						+ "\""
(146)						+ uuid
(147)						+ "\",\""
(148)						+ qName
(149)						+ "\","
(150)						+ ++childSeq
(151)						+ ",\""
(152)						+ parentID
(153)						+ "\""
(154)						+ ");";
(155)			}
(156)			stmt.executeUpdate(st);
(157)
(158)			//storing attributes
(159)			for (int i = 0; i < atts.getLength(); i++) {
(160)				stmt.executeUpdate(
(161)					"INSERT INTO Attribute VALUES(\""
(162)						+ atts.getQName(i)
(163)						+ "\",\""
(164)						+ uuid
(165)						+ "\",\""
(166)						+ atts.getValue(i)
(167)						+ "\");");
(168)			}
(169)
(170)		} catch (SQLException e) {
(171)			e.printStackTrace();
(172)			System.exit(1);
(173)		}
(174)
(175)		elementStack.push(uuid);
(176)	}
(177)
(178)	public void characters(char[] ch, int start, int length) {
(179)		String currentElement = (String) elementStack.peek();
(180)
(181)		String content = new String(ch, start, length);
(182)
(183)		try {
(184)			Statement stmt = con.createStatement();
(185)			String st = null;
(186)			ResultSet rs =
(187)				stmt.executeQuery(
(188)					"(SELECT max(SeqNo) AS max FROM Element WHERE ParentElement=\""
(189)						+ currentElement
(190)						+ "\")"
(191)						+ " UNION "
(192)						+ "(SELECT max(SeqNo) AS max FROM Text WHERE ParentElement=\""
(193)						+ currentElement
(194)						+ "\")"
(195)						+ "ORDER BY 1 DESC;");
(196)			rs.first();
(197)			int childSeq = rs.getInt("max");
(198)
(199)			st =
(200)				"INSERT INTO Text VALUES("
(201)					+ "\""
(202)					+ content
(203)					+ "\","
(204)					+ "\""
(205)					+ currentElement
(206)					+ "\","
(207)					+ ++childSeq
(208)					+ ");";
(209)			stmt.executeUpdate(st);
(210)		} catch (SQLException e) {
(211)			e.printStackTrace();
(212)		}
(213)	}
(214)
(215)	public void endElement(
(216)		String namespaceURI,
(217)		String localName,
(218)		String qName) {
(219)		elementStack.pop();
(220)	}
(221)}
Download des Beispiels


Die Logik der Abbildung der XML-Strukturen und Inhalte stellt jedes Element des Dokuments durch einen Tupel der Tabelle Element dar. Dieser Tupel enthält eine eineindeutige Identifikation für das Element (UUID, seinen qualifizierten Namen, die Identifikation des Elternelements (ParentElement) und die Position (SeqNo) des aktuellen Elements innerhalb der Kindelemente des Elternelements.
XML-Attribute bedürfen keine eigenständigen Identifikation durch einen generischen Schlüssel, sondern können --- aufgrund ihrer Eindeutigkeit für das umgebende Elternelement --- direkt durch ihren Namen identifiziert werden. Zusätzlich hierzu wird der unstrukturierte Inhalt des Attributs als Zeichenkette abgelegt. Da die Auftrittsreichenfolge von Attributen spezifikationsgemäß nicht signifikant ist, wird diese nicht mitverwaltet.
Der Inhalt eines Elements kann sich im betrachteten Ausschnitt des Information Sets ausschließlich aus weiteren Elementen, den sog. Kindelementen, oder unstrukturiertem textuellem Inhalt zusammensetzen. Für Kindelemente werden keine zusätzlichen Verwaltungsstrukturen benötigt, da diese selbst wieder als vollständige Elemente dargestellt werden können. Zur Aufnahme der textuellen Anteile genügt die Ablage der Inhalte sowie der Reihenfolgeposition innerhalb der Sequenz der Kindelemente.

Die Realisierung bedient sich eines SAX-basierten Parsers, der jedes Ereignis des Typs startElement einen Eintrag in die Tabelle Element sowie im Bedarfsfalle zu Attribute hinzufügt. Die Erzeugung der Datentupel für die textuellen Inhalte geschieht im Rahmen der Verarbeitung des characters-Ereignisses.
Zur korrekten Behandlung der XML-Hierarchie wird ein Verarbeitungskeller eingeführt, die den einzelnen Ereignisbehandlungsroutinen startElement und characters die Identifikation des aktuell verarbeiteten Elements (d.h. des Elternelements der durch die beiden Behandlungsroutinen verarbeiteten XML-Elements) zur Verfügung stellt. Die Befüllung dieses Kellers geschieht durch die Behandlungsroutine startElement sowie startDocument für die initiale Ablage von NULL als Identifikation des Elternelement-losen Wurzelelements. Entfernt werden Kellerelemente ausschließlich durch die Behandlungsroutine endElement.
Das Aktivitätsdiagramm der Abbildung 59 zeigt die Interaktion der durch den Keller gekoppelten Ereignisbehandlungsroutinen.

Versorgung der Ereignisbehandlungsroutinen mit der Identifikation des aktuellen Elements

Das Auslesen eines in die erzeugten Relationen aufgespaltenen Dokuments vollzieht sich als datenbankgestützter dynamischer Rekombinationprozeß gemäß dem durch Beispiel 134 dargestellten Beispielcode.

Beispiel 28: Erzeugen eines XML-Dokuments aus einer relationalen Datenbank
Beispiel 134: Erzeugen eines XML-Dokuments aus einer relationalen Datenbank
(1)package de.jeckle.tinyXMLDB;
(2)
(3)import java.sql.Connection;
(4)import java.sql.DriverManager;
(5)import java.sql.ResultSet;
(6)import java.sql.SQLException;
(7)import java.sql.Statement;
(8)
(9)public class DB2XML {
(10)	public static void main(String[] args)
(11)		throws ClassNotFoundException, SQLException {
(12)		Class.forName("com.mysql.jdbc.Driver");
(13)		Connection con =
(14)			(Connection) DriverManager.getConnection(
(15)				"jdbc:mysql://10.0.0.1/XML/",
(16)				"mario",
(17)				"thePassword");
(18)		Statement stmt = con.createStatement();
(19)		ResultSet rs =
(20)			stmt.executeQuery(
(21)				"SELECT ID FROM Element WHERE ParentElement IS NULL;");
(22)		rs.first();
(23)		printElement(rs.getString("ID"), con);
(24)	}
(25)	private static void printElement(String elementID, Connection con)
(26)		throws SQLException {
(27)		Statement stmt = con.createStatement();
(28)		ResultSet rs =
(29)			stmt.executeQuery(
(30)				"SELECT Name FROM Element WHERE ID=\"" + elementID + "\";");
(31)		rs.first();
(32)		String elementName = rs.getString("Name");
(33)
(34)		System.out.print("<" + elementName);
(35)		//process attributes
(36)		rs =
(37)			stmt.executeQuery(
(38)				"SELECT Name, Value FROM Attribute WHERE ParentElement=\""
(39)					+ elementID
(40)					+ "\";");
(41)		rs.beforeFirst();
(42)		while (rs.next()) {
(43)			System.out.print(
(44)				" "
(45)					+ rs.getString("Name")
(46)					+ "=\""
(47)					+ rs.getString("Value")
(48)					+ "\"");
(49)		}
(50)		System.out.print(">");
(51)		//process content
(52)		String st =
(53)			"(SELECT SeqNo FROM Element WHERE ParentElement=\""
(54)				+ elementID
(55)				+ "\")"
(56)				+ "UNION"
(57)				+ "(SELECT SeqNo FROM Text WHERE "
(58)				+ "ParentElement=\""
(59)				+ elementID
(60)				+ "\")"
(61)				+ " ORDER BY 1 DESC;";
(62)		rs = stmt.executeQuery(st);
(63)		rs.first();
(64)
(65)		int noChilds = rs.getInt("SeqNo");
(66)
(67)		ResultSet crs[] = new ResultSet[noChilds];
(68)		for (int i = 1; i <= noChilds; i++) {
(69)			crs[i - 1] =
(70)				stmt.executeQuery(
(71)					"SELECT Name, ID FROM Element WHERE ParentElement=\""
(72)						+ elementID
(73)						+ "\" AND SeqNo="
(74)						+ i
(75)						+ ";");
(76)			crs[i - 1].last();
(77)			if (crs[i - 1].getRow() == 1) {
(78)				//got an element
(79)				printElement(crs[i - 1].getString("ID"), con);
(80)			}
(81)			crs[i - 1] =
(82)				stmt.executeQuery(
(83)					"SELECT TextualContent FROM Text WHERE ParentElement=\""
(84)						+ elementID
(85)						+ "\" AND SeqNo ="
(86)						+ i
(87)						+ ";");
(88)			crs[i - 1].last();
(89)			if (crs[i - 1].getRow() == 1) {
(90)				//got text child node
(91)				System.out.print(crs[i - 1].getString("TextualContent"));
(92)			}
(93)		}
(94)		System.out.print("</" + elementName + ">");
(95)	}
(96)}
Download des Beispiels


Diskussion der Vor- und Nachteile
Die Transformation der strukturellen Eigenschaften von XML in die Strukturen eines logischen Modells erweist sich als konzeptionell leicht begehbarer Weg um XML-Daten in bestehenden DBMS abzulegen, ohne diese für die Aufnahme des neuen Datentypen zu modifizieren. Gleichzeitig gestattet es die Nutzung der vorhandenen Datenbanksysteme auch für XML-Daten. Aus diesem Grund bieten viele Hersteller, insbesondere relationaler Systeme, inzwischen Module an, die die im Rahmen der Beispiele manuell vorgenommene Abbildung bereits datenbankseitig vornehmen und so den Abbildungsschritt automatisieren.
Die hierfür notwendigen Abbildungsoperationen sind jedoch zeitintensiv, so daß die Geschwindigkeit für den Zugriff auf aufgespaltene XML-Daten deutlich hinter dem auf native (d.h. beispielsweise relationale) zurückfällt.
Dasselbe gilt für Ausleseschritte unter Anwendung von XPath oder XQuery. Dafür kann zumeist durch Erweiterungen der nativen Anfragesprache (zumeist ist dies SQL) vergleichsweise performant auf die Inhalte der früheren XML-Strukturen zugegriffen werden.
Maßnahmen zur Wahrung der strukturellen Konsistenz der verwalteten XML-Daten lassen sich teilweise bereits in Organisation der gewählten logische Repräsentation ergreifen und können zusätzlich im Rahmen des Abbildungsprozesses erfolgen.

Verwaltung von XML-Inhalten durch native XML-Datenbanken

Grundidee und Konzepte
Den im Vergleich zu den im vorhergehenden betrachteten Ansätzen jüngsten Beitrag zu den Speicherungsalternativen liefern sog. „XML-Datenbanken“, die sich das Ziel setzen XML-Daten „nativ“, d.h. ohne für den Anwender spür- und sichtbare Abbildung in logische Strukturen abzulegen.
Zwar ist dieser Ansatz durchaus konzeptionell diskussionswürdig, da er die Strukturen des logischen Modells XML auf die physische Speicherung zu übertragen sucht und damit die physische Datenunabhängigkeit verletzt, jedoch sprechen die Erfolge --- hauptsächlich hinsichtlich des Laufzeitverhaltens --- für diesen Speicherungstyp.

Beispiel
Bisher konnte sich für XML-Datenbanken noch kein Standard oder zumindest eine breite Übereinkunft hinsichtlich des Zugriffes oder der Administration herausbilden. Lediglich XQuery wird in breiten Teilen der Industrie als zukünftiger Standard einer Anfragesprache angesehen, der sich jedoch noch kaum in kommerziellen Produkten umgesetzt findet. Bis zur entgültigen Verabschiedung dieser W3C-Spezifikation werden vielfach noch XPath-basierenden proprietäre Anfragesprachen angeboten.
Das nachfolgende Beispiel beruht auf der open-source Implementierung Xindice, die im Rahmen des Apache XML-Projektes frei verfügbar ist.

Xindice organisiert die verwalteten Inhalte generell zweistufig. Die oberste Organisationseben bilden die sog. Dokumentsammlungen (Collections), welche die benannt abgelegten XML-Dokumente enthalten.
Zur Erzeugung von Sammlungen werden Administrationsrechte in Form von Ausführungsrechten für das Kommandozeilenwerkzeug xindiceadmin benötigt.
Der Aufruf xindiceadmin ac -c /db -n myCol1 erzeugt eine Sammlung unter dem Namen col1 in der Hierarchie der Dokumentsammlungen unterhalb des Astes myCollection.

Die Speicherung von Dokumenten in der Datenbank geschieht durch das Kommando xindice mit dem Parameter ad (Abkürzung für add document) und Angabe der Sammlung in die das Dokument aufgenommen werden soll (-c) , sowie des des Dokumentnamens (-n) und der Lokation des Quelldokuments im Dateisystem (-f).
So legt xindice ad -c /db/myCol1 -f /home/mario/test.xml -n test Das Dokument test.xml im Systemkatalog /home/mario in der Sammlung /db/myCol1 unter dem Namen test ab.

Zur Entnahme eines abgelegten Dokuments steht der Parameter rd (Abkürzung für retrieve for storage elsewhere) zur Verfügung. Die Angabe von xindiceadmin rd -c /db/myCol1 -n test liefert das zuvor abgelegte Dokument als Resultat in die Standardausgebe.

Zur Anfrage auf Dokumentsammlungen, d.h. auf alle Dokumente einer Sammlung gleichzeitig, stellt das Werkzeug xindice den Parameter xpath bereit. Daher liefert die Anfrage xindice xpath -c /db/myCol1 -q / alle Wurzelelemente aller in der Sammlung /db/myCol1 verwalteten Dokumente.

Diskussion der Vor- und Nachteile
XML-Datenbankmanagementsysteme offerieren einige Vorteile XML-spezifische Vorteile, wie die native Unterstützung einer auf XML-Inhalte abgestimmten Anfragesprache sowie auf diese Inhalte ausgerichtete Manipulations- und Verarbeitungsmechanismen wie XSLT-Transformationen, erfordern jedoch die Investition in ein neues DBMS, das im Betrieb zusätzlich zu den bestehenden Systemen betrieben werden muß.
Typischerweise erzielen XML-DBMS eine höhere Zugriffsgeschwindigkeit als Ansätze die XML-Daten in andere logische Strukturen überführen.
Die Verwendung von Systemen dieses Typs erfordert keine Kenntnis über den internen Aufbau und die physischen Ablageform der XML-Daten, ist jedoch in der Möglichkeit der Datenspeicherung ausschließlich auf diese Daten beschränkt, was durchaus Zweifel an der langfristigen Zukunftsfähigkeit dieser Systeme angebracht erscheinen läßt.

Vergleich der drei vorgestellten Konzepte

Der Vergleich der drei unterschiedlichen Speicherungs- und Zugriffsphilosophien offenbart, daß generell die Generizität der Speicherung, die mögliche erzielbare Flexibilität der Anfrageformulierung und die durch das System erreichbare Zugriffsgeschwindigkeit antagonistische Ziele darstellen.

Im Detail streben die Ziele die gleichzeitige Erfüllung folgender Eigenschaften an:

Abbildung 60 illustriert schematisch die quantitative Erfüllung dieser Ziele durch die drei vorgestellten Systemtypen.
Hinsichtlich der Zugriffsgeschwindikeit erzielt die dateibasierte Speicherung zweifellos die besten Ergebnisse, da sie keinerlei Einschränkung hinsichtlich der unterstützten Datenformate trifft, jedoch gleichzeitig existierende Formate auch nicht strukturell ausbeuten kann. Als Resultat hiervon können Anfragen auf als Datei veralteten XML-Dokumenten nur durch zusätzliche Werkzeuge, die außerhalb des Dateisystems als Applikation zur Verfügung stehen, formuliert werden.
Durch den Ansatz XML in andere (zumeist relationale) logische Strukturen abzubilden verschiebst sich das Gewicht signifikant zu einer Begünstigung der Anfrageforderung. Üblicherweise werden für die gemäß dem logischen Modell des verwendeten DBMS zerlegte XML-Dokumente auch die Anfragesprachen des logischen Modells angeboten. Dieser Ansatz vernachlässigt jedoch die Forderung nach generischer Speicherung, da er eine explizite Transformation in die logischen Zielstrukturen erfordert. Durch diesen notwendigen Abbildungsschritt sind generell die Zugriffsgeschwindigkeit.
XML-Datenbanksysteme versuchen einen pragmatischen Kompromiß zwischen den drei widerstreitenden Zielen zu erreichen. Dies geschieht jedoch durch Einführung eines neuen DB-Systemtyps und neuer Anfragesprachen.

Einordnung der verschiedenen XML-Datenbanktypen

Abschließend soll als ein quantifizierbarer Vergleichsparameter die Geschwindigkeit lesender- und schreibender Operationen herausgegriffen werden. Die Graphik der Abbildung 61 stellt die an den Systemtypen dieses Kapitels gemessenen Werte bei der Speicherung und anschließenden Extraktion (und Ablage in einer Datei ohne vorherige Ausgabe am Bildschirm) der XML-Darstellung des Schauspiels Macbeth dar.

Vergleich der verschiedenen XML-Datenbanktypen

Hervorstechend ist die auffallend niedrige (d.h. hoher Zeitbedarf) Zugriffsgeschwindigkeit der relationalen Abbildung aus den Beispielen 133 und 134. Diese erklärt sich einerseits durch die gewählte naive Implementierung, die auf zugriffsbeschleunigende datenbankseitige Optimierungen und entsprechende Applikationsseitige Mechanismen verzichtet aber gleichzeitig auch durch den inhärent zu leistendenen Abbildungsaufwand (insbesondere bei der Rekombination eines aufgespaltenen Dokuments während des lesenden Zugriffs), der auch durch Messungen an kommerziell verfügbaren Systemen gestützt wird.

Web-Referenzen 5: Weiterführende Links
Web-Referenzen 22: Weiterführende Links
Viele weiterführende Informationen zum Thema
Xindice, eine open-source XML-Datenbank
Tamino, ein kommerzielles XML-Datenbankprodukt
DB2, ein relationales DBMS mit XML-Erweiterungen
Oracle, ein relationales DBMS mit XML-Erweiterungen


back to top   Lösungen zu den Übungsaufgaben

 

back to top   Definitionsverzeichnis

 

Extended XLink
Extrahierender Parser
Gemischtes Inhaltsmodell
Gültiges XML-Dokument
Gültigkeit hinsichtlich eines Schemas
Lokalisierungsschritt
Namensräume
Namensraumidentifikation
Namensraumvererbung
Simpler XLink
Web Service
Wohlgeformtes XML-Dokument
XML Dokument
XML Information Set
XML Linking Language
XML-Prozessor
XML-Sprache

back to top   Schlagwortverzeichnis

 

back to top   Abbildungsverzeichnis

 

back to top   Verzeichnis der Beispiele

 

Ein erstes XML-Dokument
Element mit deklariertem Namensraum
Verschiedene Kommentarstrukturen
Verschiedene Processing Instructions
NOTATIONS
Verschiedene DOCTYPE-Deklarationen
Einige Entitätsdefinitionen
Eine ungeprüfte Entität
Beispiel eines Dokuments mit Namensräumen
Ein nicht wohl-geformtes XML-Dokument
Ein Rechnungsdokument
Eine alternative Rechnungsstruktur
Gültige URIs
Dokument mit W3C-konformen Namensräumen
Ein XHTML-Dokument mit MathML- und SVG-Inhalten
Rechnungsdokument mit überschriebenem Vorgabenamensraum
Ein XHTML-Dokument mit MathML- und SVG-Inhalten, unter Verwendung überschriebener Vorgabenamensräume
Namensraumpräfixe 1
Namensraumpräfixe 2
Namensräume im realen Einsatz
Präzedenzregel
Aufheben von Namensraumdeklarationen
Namensräume für Attribute
Einige Elementdefinitionen
Beispieldokument zur gegebenen DTD
Vollständige Beispiel-DTD
Definition einer Schemareferenz
Einige Elementdefinitionen
Nutzung benannter komplexer Typen
Einschränkende Typableitung
Erweiternde Typableitung
Ableitung eines komplexen Typen von einem Simplen
Einschränkende Spezialisierung eines simplen Typen
Bildung eines Aggregationstypen
Einige Attributdefinitionen
Vollständiges XML-Schema der Projektverwaltung
Gültiges Projektverwaltungsdokument
Ein (höchst) inkompatibles HTML-Dokument
Ein einfaches XHTML-Dokument
Nutzung von XHTML in anderen XML-Sprachen
Nutzung des XHTML-Namensraumes in einem eigenen Dokument
Ein gültiges XHTML v1.x-Dokumentfragment
... XHTML v2-konforme Formulierung
Referenzierung einer externen Bilddatei in XHTML v2
... und in XHTML v2
Überschriftsebenen in XHTML v1
Äquivalente Formulierung in XHTML v2
Erweiterte Hyperlinks in XHTML v2
Ein simple XLink
Ein transklutorischer Link
Nutzung des title-Attributs
Ein Verweis auf mehrere Ressourcen
Eingeschränkte Navigation innerhalb eines extended XLinks
Hypertext-Dokument mit HTML-konformen Verweisen
Hypertext-Dokument mit XML-Base-konformen Verweisen
XPath-Ausdruck zur Lokalisierung aller Vornamen
Platzhalter in Lokalisierungsschritten
Hierarchieunabhänigige Knoten-Lokalisierung
Selektion unter Anwendung eines Prädikats
Schrittweise Berechnung einer Selektion unter Verwendung mehrerer Prädikate
Erweiterte Projektverwaltung
Unique-Einschränkung
Zusammengesetzter Schlüssel innerhalb eines unique-Elements
Schlüsselbasierte Referenzierung
Ein minimales Stylesheet
Eine einfache Transformation
Erzeugung einer XML-Ausgabe
Übernahme bestehender Information aus dem Quelldokument
Kopieren vollständiger Elementknoten
Flexible Umbenennung und Löschung von Elementen
Bedingte Verarbeitung durch Verwendung des if-Elements
Erzeugung eines XHTML-Reports
Ausgabe Namensräume jedes Elements und Attributs eines beliebigen XML-Dokuments
Ein erstes XSL-FO-Dokument
Erzeugung einer Tabelle
Einbinden einer Graphik
Selektion mit der FOR-Klausel aus einer Menge (explizit) vorgegebener Werte
XQuery-Anfrage (FR) die alle Personen liefert
XQuery-Anfrage der Form FWR
Sortierung der Resultatmenge
XQuery-Anfrage der Form FLWR
Auswertung der FOR- und LET-Klausel
Berechnung des kartesischen Produktes zweier Mengen
XQuery-Anfrage zur Ermittlung aller Vornamen
XQuery-Anfrage zur Hierarchiebenenunabhängigen Anfrage
Bedingte Selektion in XQuery
Selektion hinsichtlich mehrerer Bedingungen in XQuery
XQuery des umfangreichen XPath-Beispiels
XQuery mit Dereferenzierung von IDREF(S)-Attributen
Erweiterung der XQuery-Mächtigkeit um eigene Funktionen
Berechnung der Fakultät einer Zahl als XQueryfunktion
XML/RDF-Darstellung
XML/RDF-Darstellung mit mehreren Prädikaten
XML/RDF-Darstellung eines mehrteiligen Prädikats
Ein einfache SAX-basierte Applikation
SAX2-Ereignisse
Häufigkeitsermittlung einzelner Elementnamen
Namensraum-konformer SAX-Parser
Namensraum-konformer SAX-Parser (nutzt SAX-Features)
Auftreten einer SAX-Exception
Behandlung einer SAXParseException
Implementierung verschiedener SAX2-Callback-Methoden
Umbenennung eines Elements
Konstruktion einer SWING-basierten Baumansicht mit SAX
Ermittlung der unterstützten DOM-Module
Ein einfacher DOM-basierter Parser
Zugriff auf Elementinformation mit DOM2
Modifikationen am Dokument mittels DOM2
Nutzung der Schnittstelle NodeList
Zugriff auf Attributinformation
Erzeugung eines XML-Dokuments im Hauptspeicher
Eine einfache XPP-basierte Applikation
Zählung der einzelnen XML-Primitive
Häufigkeitsermittlung einzelner Elementnamen
Behandlung einer XmlPullParserException
Einlesen einer XML-Datei mit Castor
Auslesen von Attribut- und Elementinformation
Erzeugung von Attribut- und Elementinhalten
Ein vollständiger SOAP-Aufruf
Nutzung der SOAP-Kopfelemente
Nutzung des SOAP-Rumpfelements
Nutzung des SOAP-Rumpfelements
Beispielwebdienst
Deploymentdeskriptor des Beispieldienstes
Aufruf des Beispielwebdiensts
SOAP-Nachricht zum Aufruf des Beispieldienstes
SOAP-Nachricht zur Übermittlung des Berechnungsergebnisses des Beispieldienstes
WSDL-Beschreibung des Beispieldienstes
Unstrukturierte Speicherung von XML-Dokumenten in einer Datenbank
Auslesen eines unstrukturierte gespeicherten XML-Dokuments
Speichern eines XML-Dokuments in einer relationalen Datenbank
Erzeugen eines XML-Dokuments aus einer relationalen Datenbank




separator line
Service provided by Mario Jeckle
Generated: 2004-06-11T07:12:55+01:00
Feedback Feedback       SiteMap SiteMap
This page's original location This page's original location: http://www.jeckle.de/vorlesung/xml/script.html
RDF metadata describing this page RDF description for this page