XML kurz zusammengefasst

(Auszug aus "Java und XSLT" von Eric M. Burke)

   

   

XML ist ein Format zur Speicherung strukturierter Daten. Obwohl es HTML sehr ähnlich sieht, ist XML wesentlich strikter in Bezug auf Anführungszeichen, korrekt abgeschlossene Tags und andere solche Details. XML definiert auch keine Tag-Bezeichnungen; Autoren müssen also ihre eigenen Tags erfinden oder darauf warten, daß jemand eine passende XML-Auszeichnungssprache (markup language) standardisiert. Eine Auszeichnungssprache ist im Prinzip eine definierte Menge von Tags mit semantischer Bedeutung hinter jedem Tag; XSLT ist eine solche Auszeichnungssprache, denn es verwendet die XML-Syntax.

Die Begriffe Element und Tag werden oft synonym verwendet. Beide werden Sie in diesem Buch finden. Vom technischen Standpunkt gesehen, bezeichnet der Begriff Element das repräsentierte Konzept, während Tag die eigentliche Auszeichnung im Dokument meint. <kunde> ist also das Tag, das das Elementkunde in einem Computerprogramm repräsentiert.

SGML, XML und Auszeichnungssprachen

SGML (Standard Generalized Markup Language) bildet die Basis für HTML, XHTML, XML und XSLT; allerdings für jede von ihnen auf eine andere Art. Die folgende Abbildung zeigt die Beziehungen zwischen den Technologien.

SGML-Stammbaum

Abbildung: SGML-Stammbaum

SGML ist eine sehr hochentwickelte Metasprache, geschaffen für komplexe Dokumentationsanwendungen. Als Metasprache definiert SGML Syntaxregeln für Tags, ohne die spezifischen Tags selbst zu definieren. HTML dagegen ist eine Auszeichnungssprache, die mittels SGML implementiert wurde. Eine Auszeichnungssprache definiert einen eigenen Satz von Tags, wie beispielsweise <h1> und <p>. Weil HTML eine Auszeichnungssprache und keine Metasprache ist, können Sie nicht einfach neue Tags hinzufügen in der stillen Hoffnung, ein Browserhersteller werde die Tags schon implementieren.

XML ist, wie aus der obigen Abbildung ersichtlich, eine Untermenge von SGML. XML-Dokumente sind kompatibel zu SGML-Dokumenten, XML ist jedoch eine sehr viel weniger umfangreiche Sprache. Eines der erklärten Ziele von XML ist seine Einfachheit, denn es wird im Web verwendet, wo Bandbreite und begrenzte Rechenleistung der Clients von Bedeutung sind. XML ist leicht zu parsen und zu überprüfen, wodurch es eine bessere Performance bietet als SGML. Da XML auch eine Metasprache ist, definiert es ebenfalls keine eigenen Tags. XSLT als Auszeichnungssprache, die unter Verwendung von XML implementiert wurde, wird in den nächsten beiden Kapiteln detailliert besprochen.

XHTML ist wie XSLT eine XML-basierte Auszeichnungssprache. XHTML ist darauf ausgelegt, HTML zu ersetzen und daher fast vollständig kompatibel mit existierenden Webbrowsern. Anders als HTML ist XHTML strikt XML-basiert, und die Regeln für wohlgeformte Dokumente sind sehr genau festgelegt. Das macht es den Herstellern bedeutend einfacher, Editoren oder Programmierhilfsmittel für XHTML zu entwickeln, denn die Syntax ist nicht nur wesentlich besser vorherzusagen, sondern kann wie jedes andere XML-Dokument überprüft werden. Viele der Beispiele in diesem Buch sind anstelle von HTML in XHTML geschrieben, obwohl XSLT beide Formate problemlos handhaben kann.

Mit Blick auf fortgeschrittenere Techniken zur Verarbeitung von XML mit XSLT werden wir feststellen, daß nicht immer XML vorliegt, wenn eine Textdatei Tags enthält. In gewisser Weise sind XML-Dateien und ihre Tags nichts anderes als eine serialisierte Darstellung der zugrundeliegenden XML-Elemente. Diese serialisierte Form eignet sich zur Speicherung von XML-Daten in Dateien, ist unter Umständen aber nicht die effizienteste Art des systemübergreifenden Datenaustauschs oder der Modifikation der zugrundeliegenden Daten. Bei besonders umfangreichen Dokumenten ist eine relationale oder objektorientierte Datenbank wesentlich leistungsstärker und besser skalierbar als native XML-Textdateien.

XHTML-Grundlagen

XHTML ist eine Empfehlung des W3C für die Zukunft von HTML. Basierend auf HTML 4.0, ist XHTML kompatibel zu existierenden Webbrowsern und entspricht vollständig den Anforderungen von XML. Ein sauber verfaßtes XHTML-Dokument ist also immer ein wohlgeformtes XML-Dokument. Außerdem müssen XHTML-Dokumente sich an eine der XHTML-DTDs halten. Dadurch können XHTML-Seiten mit Standard-XML-Parsern wie Apaches Crimson auf Gültigkeit überprüft werden.

XHTML ist modular gestaltet, damit beispielsweise für mobile Geräte wie Handys Teilmengen gebildet werden können. XHTML Basic, ebenfalls eine W3C-Empfehlung, ist ein Ergebnis dieser Modularisierung und wird sicher in Zukunft zu einem Begriff im Zusammenhang mit Drahtlos-Anwendungen werden.

Hier nun ein XHTML-Beispieldokument:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Hallo Welt!</title>
    </head>
    <body>
        <p>Hallo Welt!</p>
    </body>
</html>

Einige der wichtigsten XHTML-Regeln sind:

  • XHTML-Dokumente müssen aus wohlgeformtem XML bestehen und sich an eine der XHTML-DTDs halten. Wie es von XML erwartet wird, müssen alle Elemente korrekt abgeschlossen werden, die Werte von Attributen müssen in Anführungszeichen stehen, und die Elemente müssen korrekt verschachtelt sein.
  • Das <!DOCTYPE ...>-Tag ist zwingend erforderlich.
  • Anders als in HTML müssen alle Tags klein geschrieben werden.
  • Das Wurzelelement muß wie im obigen Beispiel <html> heißen und den XHTML-Namensraum bezeichnen.
  • <head> und <body> müssen im Dokument enthalten sein.

Das vorangegangene Dokument hält sich an die strict DTD, die veraltete HTML-Tags neben vielen stilbezogenen Tags verbietet. Zwei weitere DTDs, transitional und frameset, bieten eine bessere Kompatibilität zu existierenden Webbrowsern, sollten aber wenn möglich nicht verwendet werden. Vollständige Informationen finden Sie in den Spezifikationen des W3C.

XML-Syntax

Das Beispiel bundespraesidenten.xml zeigt ein XML-Beispieldokument mit Informationen über ehemalige Bundespräsidenten. Das Dokument wird als wohlgeformt bezeichnet, weil es sich an verschiedene Grundregeln für korrekte XML-Formatierung hält.

bundespraesidenten.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE bundespraesidenten SYSTEM "bundespraesidenten.dtd">
<bundespraesidenten>
    <bundespraesident>
        <amtsperiode von="1959" bis="1969"/>
        <name>
            <vorname>Heinrich</vorname>
            <nachname>Lübke</nachname>
        </name>
        <partei>CDU</partei>
    </bundespraesident>
    <bundespraesident>
        <amtsperiode von="1969" bis="1974"/>
        <name>
            <titel>Dr.</titel>
            <titel>Dr.</titel>
            <vorname>Gustav</vorname>
            <mittelinitial>W.</mittelinitial>
            <nachname>Heinemann</nachname>
        </name>
        <partei>SPD</partei>
    </bundespraesident>
    <!-- Die übrigen Bundespräsidenten werden ausgelassen -->
</bundespraesidenten>

In HTML sind ein fehlendes Tag hier und da oder falsch plazierte Anführungszeichen nichts Schlimmes. Die Browser versuchen alles, um das schlecht formatierte Dokument trotzdem anzuzeigen. Dadurch wird das Web zu einer angenehmeren Umgebung, denn Nutzer werden nicht ständig mit Syntaxfehlern bombardiert.

Da die primäre Aufgabe von XML darin besteht, strukturierte Daten zu repräsentieren, ist Wohlgeformtheit sehr wichtig. Wenn zwei Bankrechner Daten austauschen, und die übertragene Nachricht ist in irgendeiner Weise beschädigt, muß das empfangende System die Nachricht ablehnen, um keine falschen Annahmen zu riskieren. Das ist für XSLT-Programmierer wichtig zu verstehen, denn XSLT selbst wird ja auch in XML formuliert. Wenn Sie also ein Stylesheet schreiben, halten Sie sich immer an die Grundregeln für wohlgeformte Dokumente.

Alle wohlgeformten XML-Dokumente müssen exakt ein Wurzelelement haben. Im Beispiel Bundespraesidenten.xml ist das Wurzelelement <bundespraesidenten>. Es bildet die Basis einer Baumstruktur von Daten, in der jedes andere Element genau ein Elternelement und null oder mehr Kindelemente hat. Alle Elemente müssen korrekt abgeschlossen und verschachtelt sein:

<name>
 <vorname>Heinrich</vorname>
 <nachname>Lübke</nachname>
</name>

Obwohl Whitespace (Leerzeichen, Tabulatoren und Zeilenvorschübe) zwischen Elementen eigentlich irrelevant ist, kann es die Lesbarkeit erheblich erhöhen, wenn Sie die Elemente ordentlich einrücken. Auch wenn XML-Parser den Whitespace bestehen lassen, werden die zugrundeliegenden Elemente dadurch nicht in ihrer Bedeutung verändert. Andere Dinge verändern die Bedeutung der Elemente jedoch nachhaltig. Im folgenden Beispiel müßte das <vorname>-Tag mit einem korrespondierenden </vorname>-Tag abgeschlossen werden. Der folgende XML-Code wäre unzulässig, da die Tags nicht korrekt verschachtelt sind:

<name>
  <vorname>Heinrich
    <nachname>Lübke</vorname>
  </nachname>
</name>

XML bietet eine alternative Syntax zum Abschluß von Elementen, die weder Inhalt noch Kinder haben, formal als leere Elemente bezeichnet. Das <amtsperiode>-Element ist ein solches Beispiel:

<amtsperiode von="1959" bis="1969"/>

Der schließende Schrägstrich deutet an, daß dieses Element keinen Inhalt hat, obwohl es Attribute enthalten kann. Ein Attribut ist ein Name-Wert-Paar wie von="1959". Als eine weitere Anforderung an wohlgeformtes XML müssen alle Attributwerte in einfache ('') oder doppelte ("") Anführungszeichen eingeschlossen sein.

Manche Bundespräsidenten hatten ein Mittelinitial in ihrem Namen, andere hatten einen oder mehrere Titel. In unserer XML-Beispieldatei sind dies optionale Elemente. Gustav Heinemann hatte beispielweise einen zweiten Vornamen und außerdem noch zwei Titel:

<bundespraesident>
    <amtsperiode from="1969" bis="1974"/>
    <name>
        <titel>Dr.</titel>
        <titel>Dr.</titel>
        <vorname>Gustav</vorname>
        <mittelinitial>W.</mittelinitial>
        <nachname>Heinemann</nachname>
    </name>
    <partei>SPD</partei>
</bundespraesident>

Groß- und Kleinschreibung ist ebenfalls wichtig in XML. Anders als HTML unterscheidet XML zwischen diesen. Das heißt, <bundespraesident> ist nicht dasselbe wie <BUNDESPRAESIDENT>. Es spielt keine Rolle, welche Schreibweise Sie verwenden, solange Sie es konsistent tun. Wie Sie wahrscheinlich schon erraten haben, unterscheiden auch XHTML-Dokumente als XML-Dokumente zwischen groß- und kleingeschriebenen Tags. In XHTML müssen alle Tags klein geschrieben werden, also beispielsweise <html>, <body> und <head>.

Die folgende Liste faßt die Grundregeln für ein wohlgeformtes XML-Dokument zusammen:

  • Es muß exakt ein Wurzelelement enthalten; der Rest des Dokuments bildet eine Baumstruktur, in der jedes Element in genau einem Elternelement enthalten ist.
  • Alle Elemente müssen korrekt abgeschlossen werden. <name>Leo</name> ist beispielsweise korrekt abgeschlossen, da das <name>-Tag mit </name> beendet wird. In XML können auch leere Elemente der Form <ledig/> erzeugt werden.
  • Elemente müssen korrekt verschachtelt werden. Das ist erlaubt:
<b><i>fett und kursiv</i></b>

Das hier nicht:

<b><i>fett und kursiv</b></i>
  • Attribute müssen in einfachen oder doppelten Anführungszeichen eingeschlossen werden. Beispiel:
<datum monat="april" tag='05' jahr="1979"/>
  • Attribute müssen Name-Wert-Paare enthalten. Einige HTML-Elemente enthalten Markierungsattribute, wie <td nowrap>. In XHTML würde dies als <td nowrap="nowrap"/> geschrieben. Das ist kompatibel zu XML und sollte in existierenden Browsern funktionieren.

Dies ist nicht die komplette Liste der Regeln, aber es sollten genug sein für das Verständnis der Beispiele in diesem Buch. Sie werden zustimmen, daß die meisten HTML-Dokumente nicht wohlgeformt sind. Viele Tags, wie <br> oder <hr>, verletzen die Regel, daß alle Tags korrekt abgeschlossen werden müssen. Darüber hinaus beschwert sich kein Browser, wenn Attributwerte nicht in Anführungszeichen stehen. Daraus wird für uns beim Schreiben von XSLT-Stylesheets noch einige Verwirrung entstehen, denn die Stylesheets werden ja in XML geschrieben und geben oftmals HTML aus. In der Praxis bedeutet das, daß ein Stylesheet nur schwer nicht-wohlgeformtes HTML erzeugen kann, da es selbst nur wohlgeformtes XML enthalten darf. XHTML wird sich da schon leichter ausgeben lassen, denn es ist ja ebenfalls XML.

Validierung

Ein wohlgeformtes XML-Dokument hält sich an die gerade skizzierten, elementaren Syntaxrichtlinien. Ein gültiges Dokument geht noch einen Schritt weiter, denn es hält sich zusätzlich an eine Dokumenttyp-Definition (DTD) oder ein XML-Schema. Um als gültig angesehen zu werden, muß ein XML-Dokument zunächst wohlgeformt sein. Einfach ausgedrückt, dienen DTDs traditionell der Validierung und XML-Schemata sind ihr logischer Nachfolger. XML Schema ist eine weitere Spezifikation des W3C und bietet wesentlich höher ausgefeiltere Möglichkeiten zur Validierung als DTDs. Da XML Schema noch sehr neu ist, werden DTDs für eine gewisse Übergangszeit weiterverwendet.

Zeile 2 im Beispiel Bundespraesidenten.xml enthält die folgende Dokumenttyp-Deklaration:

<!DOCTYPE bundespraesidenten SYSTEM "bundespraesidenten.dtd">

Diese Deklaration bezieht sich auf die im selben Unterverzeichnis wie bundespraesidenten.xml existierende DTD. Vielfach wird die DTD aber auch über einen URI referenziert:

<!DOCTYPE bundespraesidenten SYSTEM "http://bund.de/dtds/bundesprasesidenten.dtd">

Wo auch immer sich die DTD nun befindet, sie enthält immer Regeln zur Definition der erlaubten Strukturen für die XML-Daten. Das folgende Beispiel zeigt die DTD für unsere Liste der Bundespräsidenten.

bundespraesidenten.dtd

<!ELEMENT bundespraesidenten (bundespraesident+)>
<!ELEMENT bundespraesident (amtsperiode, name, partei)>
<!ELEMENT name (titel*, vorname, mittelinitial*, nachname, spitzname?)>
<!ELEMENT titel (#PCDATA)>
<!ELEMENT vorname (#PCDATA)>
<!ELEMENT mittelinitial (#PCDATA)>
<!ELEMENT nachname (#PCDATA)>
<!ELEMENT spitzname (#PCDATA)>
<!ELEMENT partei (#PCDATA)>
<!ELEMENT amtsperiode EMPTY>
<!ATTLIST amtsperiode von CDATA #REQUIRED bis CDATA #REQUIRED>

In der ersten Zeile der DTD ist definiert, daß das <bundespraesidenten>-Element ein oder mehrere <bundespraesident>-Kindelemente haben kann. Der <bundespraesident> wiederum hat eine <amtsperiode>, einen <name> und eine <partei> in genau dieser Reihenfolge. Wenn die XML-Daten nicht diesen Regeln entsprechen, werden sie von einem validierenden XML-Parser als ungültig abgelehnt.

Das <name>-Element kann den folgenden Inhalt haben: null oder mehrere <titel>, genau ein <vorname> gefolgt von null oder mehr <mittelinitial>-Elementen, genau ein <nachname> und danach kein oder genau ein <spitzname>.

Beim Inhalt von Elementen wie <vorname>Gustav</vorname> spricht man von #PCDATA, was für parsed character data, also geparste Zeichen-Daten, steht. Dabei handelt es sich um normalen Text, der Auszeichnungen wie beispielsweise verschachtelte Tags enthalten kann. Der CDATA-Typ wird für Attributwerte verwendet und kann keine solchen Auszeichnungen enthalten. Das heißt, ein <-Zeichen in Attributwerten muß in Ihren XML-Dokumenten als &lt; kodiert werden. Das <amtsperiode>-Element hat den Vermerk EMPTY, was bedeutet, es kann keinen Inhalt haben, Attribute dürfen darin trotzdem vorkommen. Die Beispiel-DTD spezifiziert, daß das <amtsperiode>-Element von- und bis-Attribute enthalten muß:

<amtsperiode von="1969" bis="1974"/>

Die übrigen Syntaxregeln für DTDs werden wir in diesem Buch nicht besprechen, hauptsächlich weil sie nicht allzu viel Einfluß auf unseren Code haben, wenn wir XSLT-Stylesheets darauf anwenden. DTDs werden nämlich primär während des Parsing-Vorgangs verwendet, wenn die XML-Daten aus einer Datei in den Speicher eingelesen werden. Wird XML für eine Website erstellt, wird man eher neues XML erzeugen als bestehendes zu parsen, daher gibt es einfach weniger zu validieren. Ein Bereich, in dem wir DTDs aber auf jeden Fall benutzen werden, ist das Entwickeln von Modultests für unseren Java- und XSLT-Code unter Entwicklungsumgebungen, Testen und Performance.

Java und XML

Im Verlauf dieses Buches werden Java-APIs für XML wie SAX, DOM und JDOM verwendet werden. Obwohl wir nicht zu sehr ins Detail gehen wollen, was die spezifischen Parsing-APIs betrifft, ist es trotzdem wichtig zu verstehen, was die jeweiligen APIs tun und wie sie in die XML-Landschaft passen, denn die Java-basierten XSLT-Tools basieren auf diesen Technologien. Für tiefergehende Information zu einem dieser Themen werfen Sie am besten einen Blick in Brett McLaughlins Buch Java und XML (O’Reilly).

Der Begriff Parser bezeichnet ein Software-Tool, das XML-Daten in den Speicher lädt. Meistens stammen diese Daten aus einer Textdatei, obwohl Java-XML-Parser die XML-Daten auch aus jedem Java-InputStream oder sogar von einer URL einlesen können. Wird eine DTD oder ein Schema verwendet, werden validierende Parser während des Parsing-Vorgangs zusätzlich sicherstellen, daß die XML-Daten gültig sind. Wenn also Ihre XML-Daten einmal erfolgreich in den Speicher geladen wurden, muß erheblich weniger Java-Code zu Überprüfungszwecken geschrieben werden.

SAX

In Java-Programmiererkreisen heißt die gegenwärtig am häufigsten eingesetzte Parsing-Methode SAX (Simple API for XML). SAX ist eine freie API, erhältlich bei David Megginson und Mitgliedern der XML-DEV-Mailingliste. SAX kann auf Megginson Technologies: Simple API for XML heruntergeladen werden. (Da SAX von allen bekannten XML-Parsern unterstützt wird und auch darin enthalten ist, ist der direkte Download der API meist nicht erforderlich.) Obwohl es eine SAX-Implementierung für verschiedene andere Programmiersprachen gibt, werden wir uns auf die Java-spezifische Funktionalität konzentrieren. SAX ist zuständig für das Scannen der XML-Daten vom Anfang bis zum Ende, wobei es Ereignisbenachrichtigungen sendet, wenn es auf Elemente, Text und andere Bestandteile stößt; es liegt am Empfänger dieser Benachrichtungen, die Daten geeignet zu verarbeiten. SAX-Parser speichern nicht die kompletten Daten im Speicher, weswegen sie in der Lage sind, auch bei sehr großen Dateien schnell zu arbeiten.

Im Augenblick existieren zwei Versionen von SAX: 1.0 und 2.0. In Version 2.0 wurden viele Änderungen gemacht; die Beispiele zu SAX in diesem Buch verwenden diese Version. Die meisten SAX-Parser sollten die älteren Klassen und Schnittstellen aus Version 1.0 aber unterstützen, Sie bekommen jedoch bei Verwendung von 1.0 in jedem Fall eine Compiler-Warnung ausgegeben, daß Sie eine veraltete Version benutzen.

Die Implementierung von Java-SAX-Parsern verwendet eine Reihe von Interfaces. Die wichtigste Schnittstelle dabei ist org.xml.sax.ContentHandler, welche Methoden wie startDocument( ), startElement( ), characters( ), endElement( ) und endDocument( ) deklariert. Während des Parsing-Vorgangs wird startDocument( ) einmal aufgerufen, danach werden startElement( ) und endElement( ) jeweils einmal für jedes Tag in den XML-Daten aufgerufen.

Bei dem folgenden XML

<vorname>Gustav</voname>

wird die startElement()-Methode aufgerufen, gefolgt von characters(). Danach kommt endElement(). Die characters()-Methode liefert in diesem Beispiel den Text "Gustav" zurück. Dieser grundlegende Vorgang wiederholt sich bis zum Ende des Dokuments, wo endDocument() aufgerufen wird.

Hinweis:
Abhängig von der SAX-Implementierung trennt die characters( )-Methode zusammenhängende Zeichenfolgen in verschiedene Stücke. In diesem Fall wird die characters( )-Methode mehrfach aufgerufen, bis die Zeichenfolgen vollständig geparst sind.

Da es sich bei ContentHandler um eine Schnittstelle handelt, muß sie im Code Ihrer Anwendung irgendwie implementiert werden, mit anderen Worten, die Anwendung muß etwas tun, wenn der Parser diese Methoden aufruft. SAX liefert eine Klasse DefaultHandler, die die ContentHandler-Schnittstelle implementiert. Um DefaultHandler zu verwenden, leiten Sie einfach eine Unterklasse davon ab und überschreiben die Methoden, die für Sie interessant sind. Die anderen Methoden können einfach ignoriert werden, denn es handelt sich dabei schlicht um leere Methoden. Wenn Sie sich mit der AWT-Programmierung auskennen, werden Sie feststellen, daß diese Programmierweise identisch ist mit der bei Ereignis-Adapterklassen wie beispielsweise java.awt.event.WindowAdapter.

Sie werden sich jetzt vielleicht fragen, was SAX mit XSLT zu tun hat. Typischerweise haben XSLT-Prozessoren die Fähigkeit, ihre Eingaben aus einer Reihe von SAX-Events zu entnehmen, anstatt die Eingaben aus statischen XML-Dateien zu holen. Nicht ganz offensichtlicherweise können Sie sehr einfach Ihre eigenen SAX-Events generieren – ohne einen SAX-Parser zu verwenden. Dieser ruft ja letzlich nur eine Reihe von Methoden der ContentHandler-Schnittstelle auf, es ist also kein Problem, einen Pseudo-Parser zu schreiben, der dasselbe macht. Wir werden hier unter XSLT-Verarbeitung mit Java mehr ins Detail gehen, wenn von SAX in Verbindung mit einem XSLT-Prozessor zur Transformation von Nicht-XML-Daten wie Ergebnissen einer Datenbankabfrage oder Dateien mit CSV-Inhalten (CSV steht für Comma Separated Values, also durch Kommas abgetrennte Werte) die Rede sein wird.

DOM

Das Document Object Model (DOM) ist eine API, die es Computerprogrammen ermöglicht, die einem XML-Dokument zugrundeliegenden Datenstrukturen zu verändern. DOM ist eine Empfehlung des W3C, die in den verschiedensten Programmiersprachen implementiert wurde. Das Speicherabbild von XML wird normalerweise als DOM-Baum bezeichnet, denn DOM ist eine baumförmige Datenstruktur. Die Wurzel des Baums repräsentiert das XML-Dokument selbst unter Verwendung der org.w3c.dom.Document-Schnittstelle. Das Wurzelelement des Dokuments andererseits wird über die org. w3c.dom.Element-Schnittstelle dargestellt. Im Beispiel mit den Bundespräsidenten ist das <bundespraesidenten>-Element das Wurzelelement des Dokuments. Bei DOM ist beinahe jede Schnittstelle von org.w3c.dom.Node abgeleitet; Document und Element bilden da keine Ausnahme. Die Node-Schnittstelle bietet eine Vielzahl an Methoden, um konsistent durch den DOM-Baum zu navigieren und diesen zu modifizieren.

Seltsamerweise bietet die DOM Level 2-Empfehlung keine Standardmechanismen zum Lesen oder Schreiben von XML-Daten. Statt dessen wird dies in der Implementierung eines jeden Anbieters ein wenig anders gelöst. Eigentlich ist das kein großes Problem, denn jede DOM-Implementierung bietet Mechanismen zum Parsen und Serialisieren oder Ausgeben von XML-Dateien. Als unerwünschter Nebeneffekt wird sich beim Lesen und Schreiben von XML anbieterspezifischer Code in jede Ihrer Anwendungen einschleichen.

Hinweis:
Als dieses Buch verfaßt wurde, war ein neues W3C-Dokument mit dem Titel »Document Object Model (DOM) Level 3 Content Models and Load and Save Specification« im Entwurfsstadium. Wenn diese Spezifikation einmal zur Empfehlung des W3C wird, enthält DOM die bislang fehlenden Mechanismen zum Lesen und Schreiben von XML.

Da DOM keinen Standardweg zum Einlesen von XML-Daten in den Speicher spezifiziert, delegieren die meisten (wenn nicht sogar alle) DOM-Implementierungen diese Aufgabe an einen bestimmten Parser. Für Java ist SAX die bevorzugte Parsing-Technologie. Die folgende Abbildung zeigt das typische Zusammenspiel zwischen SAX-Parsern und DOM-Implementierungen.

Zusammenspiel zwischen DOM und SAX

Abbildung: Zusammenspiel zwischen DOM und SAX

Obwohl es wichtig ist zu verstehen, wie die einzelnen Akteure zusammenspielen, werden wir in diesem Buch nicht allzu detailliert auf die Parsing-Syntax eingehen. Wenn wir zu komplexeren Themen fortschreiten, werden wir XML fast immer dynamisch generieren, anstatt es aus statischen XML-Dateien einzulesen. Lassen Sie uns daher einmal näher betrachten, wie DOM eingesetzt werden kann, um ein vollkommen neues Dokument zu erzeugen. Das folgende Beispiel enthält XML für eine kleine Bibliothek.

Beispiel: bibliothek.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE bibliothek SYSTEM "bibliothek.dtd">
<bibliothek>
    <!-- Das ist übrigens ein XML-Kommentar -->
    <verlag id="oreilly">
        <name>O'Reilly</name>
        <strasse>Balthasarstrasse 81</strasse>
        <ort>Köln</ort>
        <plz>50670</plz>
    </verlag>
    <buch verlag="oreilly" isbn="3-89721-219-6">
        <ausgabe>1</ausgabe>
        <veroeffentlichungsDatum mm="02" jj="2000"/>
        <titel>XML kurz und gut</titel>
        <autor>Robert Eckstein</autor>
    </buch>
    <buch verlag="oreilly" isbn="3-89721-280-3">
        <ausgabe>1</ausgabe>
        <veroeffentlichungsDatum mm="03" jj="2001"/>
        <titel>Java und XML</titel>
        <autor>Brett McLaughlin</autor>
    </buch>
</bibliothek>

Wie in bibliothek.xml zu sehen, besteht eine <bibliothek> aus <verlag>-Elementen und <buch>-Elementen. Um dieses XML zu erzeugen, werden wir Java-Klassen mit den Namen Bibliothek, Buch und Verlag verwenden. Diese Klassen werden hier nicht gezeigt, sie sind aber auch wirklich sehr einfach gehalten. Hier beispielsweise ein Ausschnitt der Buch-Klasse:

public class Buch {
  private String autor;
  private String titel;
  ...
  
  public String getAutor( ) {
  return this.autor;
  }
  
  public String getTitel( ) {
  return this.titel;
  }
  ...
}

Jede dieser drei Hilfsklassen wird lediglich verwendet, um Daten vorzuhalten. Der Code zur XML-Erzeugung ist in einer separaten Klasse BibliothekDOMCreator gekapselt. Diese Klasse ist im folgenden Beispiel zu sehen in.

Beispiel: XML-Erzeugung mit DOM

package chap1;

import java.io.*;
import java.util.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
* Ein Beispiel aus Kapitel 1. Es erzeugt die XML-Datei für Bibliothek mittels der
* DOM API.
*/
public class BibliothekDOMCreator {
  
  /**
  * Erzeuge ein neues DOM org.w3c.dom.Document-Objekt aus dem spezifizierten
  * Bibliothek-Objekt.
  *
  * @param bibliothek: eine anwendungsdefinierte Klasse, die eine
  * Liste von Verlagen und Büchern bereithält.
  * @return: ein neues DOM-Dokument.
  */
  public Document createDocument(Bibliothek bibliothek)
      throws javax.xml.parsers.ParserConfigurationException {
    // Verwende Suns Java-API für XML-Parsing, um das DOM-Dokument
    // zu erzeugen
    javax.xml.parsers.DocumentBuilderFactory dbf =
      javax.xml.parsers.DocumentBuilderFactory.newInstance( );
    javax.xml.parsers.DocumentBuilder docBuilder =
      dbf.newDocumentBuilder( );
    Document doc = docBuilder.newDocument( );
        
    // ACHTUNG: DOM hat keine eingebaute Methode zum Erzeugen von:
    // <!DOCTYPE bibliothek SYSTEM "bibliothek.dtd">
    // Apaches Xerces unterstützt die createDocumentType-Methode
    // über die DocumentImpl-Klasse, um das zu machen. Wird hier nicht verwendet.
    // erzeuge das <bibliothek>-Wurzelelement des Dokuments
    Element root = doc.createElement("bibliothek");
    doc.appendChild(root);
        
    // füge dem <bibliothek>-Element <verlag>-Kindelemente hinzu
    Iterator verlagsIter = bibliothek.getVerlage().iterator( );
    while (verlagsIter.hasNext( )) {
      Verlag verlag = (Verlag) verlagsIter.next( );
      Element verlagElem = createVerlagElement(doc, verlag);
      root.appendChild(verlagElem);
    }
        
    // füge nun <buch>-Kindelemente zum <bibliothek>-Element hinzu
    Iterator buchIter = bibliothek.getBuecher().iterator( );
    while (buchIter.hasNext( )) {
      Buch buch = (Buch) buchIter.next( );
      Element buchElem = createBuchElement(doc, buch);
      root.appendChild(buchElem);
    }
    return doc;
  }

  private Element createVerlagElement(Document doc, Verlag verlag) {
    Element verlagElem = doc.createElement("verlag");
    
    // setze das Attribut id="oreilly"
    verlagElem.setAttribute("id", pub.getId( ));
    
    Element name = doc.createElement("name");
    name.appendChild(doc.createTextNode(verlag.getName( )));
    verlagElem.appendChild(name);
    
    Element strasse = doc.createElement("strasse");
    strasse.appendChild(doc.createTextNode(verlag.getStrasse( )));
    verlagElem.appendChild(strasse);
    
    Element stadt = doc.createElement("stadt");
    stadt.appendChild(doc.createTextNode(verlag.getStadt( )));
    verlagElem.appendChild(stadt);
    
    Element plz = doc.createElement("plz");
    plz.appendChild(doc.createTextNode(pub.getPlz( )));
    verlagElem.appendChild(plz);
    
    return verlagElem;
  }
  
  private Element createBuchElement(Document doc, Buch buch) {
    Element buchElem = doc.createElement("buch");
    
    buchElem.setAttribute("verlag", buch.getVerlag().getId( ));
    buchElem.setAttribute("isbn", buch.getIsbn( ));
    
    Element ausgabe = doc.createElement("ausgabe");
    ausgabe.appendChild(doc.createTextNode(Integer.toString(buch.getAusgabe( ))));
    buchElem.appendChild(ausgabe);
    
    Element veroeffentlichungsDatum = doc.createElement("veroeffentlichungsDatum");
    veroeffentlichungsDatum.setAttribute("mm",
      Integer.toString(buch.getVeroeffentlichungsMonat( )));
    veroeffentlichungsDatum.setAttribute("jj",
      Integer.toString(buch.getVeroeffentlichungsJahr( )));
    buchElem.appendChild(veroeffentlichungsDatum);
    
    Element titel = doc.createElement("titel");
    titel.appendChild(doc.createTextNode(buch.getTitel( )));
    buchElem.appendChild(titel);
    
    Element autor = doc.createElement("autor");
    autor.appendChild(doc.createTextNode(buch.getAutor( )));
    buchElem.appendChild(autor);
    return buchElem;
  }
  
  public static void main(String[] args) throws IOException,
      javax.xml.parsers.ParserConfigurationException {
    Bibliothek bibl = new Bibilothek( );
    BibliothekDOMCreator bdc = new BibliothekDOMCreator( );
    Document doc = bdc.createDocument(bibl);
        
    // Schreibe das Dokument mit Apache Xerces
    // gib das Dokument mit UTF-8-Kodierung aus; rücke jede Zeile ein
        
    org.apache.xml.serialize.OutputFormat fmt =
      new org.apache.xml.serialize.OutputFormat(doc, "UTF-8", true);
    org.apache.xml.serialize.XMLSerializer serial =
      new org.apache.xml.serialize.XMLSerializer(System.out, fmt);
    serial.serialize(doc.getDocumentElement( ));
  }
}

Das Beispiel beginnt mit der üblichen Folge von import-Anweisungen. Beachten Sie, daß zwei Interfaces aus org.w3c.dom.* importiert werden, Pakete wie org.apache.xml.serialize.* hingegen nicht. Der Code ist so geschrieben, um klarzumachen, daß viele Klassen, die Sie verwenden werden, nicht Bestandteil der Standard-DOM-API sind. Diese Klassen verwenden alle vollständig ausgeschriebene Klassen- und Paketnamen im Code. Obwohl DOM selbst eine W3C-Empfehlung ist, sind viele gebräuchliche Aufgaben nicht von der Spezifikation abgedeckt und können nur mit Hilfe von anbieterspezifischem Code bewältigt werden.

Das Zugpferd dieser Klasse ist die Methode createDocument, die ein bibliothek-Objekt als Parameter erwartet und ein org.w3c.dom.Document-Objekt zurückliefert. Diese Methode kann eine ParserConfigurationException auslösen, deren Auftreten darauf hindeutet, daß Suns Java-API für XML-Parsing (JAXP) keinen XML-Parser finden konnte:

public Document createDocument(Bibliothek bibliothek)
  throws javax.xml.parsers.ParserConfigurationException {

Die Bibliothek-Klasse speichert nur die Daten über eine persönliche Büchersammlung. In einer echten Anwendung wäre die Bibliothek-Klasse darüber hinaus wohl noch zuständig für die Verbindung zu einer Backend-Datenquelle. Diese Anordnung stellt eine klare Trennung zwischen Code zur XML-Generierung und der zugrundeliegenden Datenbank sicher. Der einzige Zweck der Klasse BibliothekDOMCreator ist die Erstellung der DOM-Bäume, damit ein Programmierer leicht an der Klasse arbeiten kann, während ein anderer sich auf die Implementierung von Bibliothek, Buch und Verlag konzentrieren kann.

Im nächsten Schritt wird nun ein DOM Document-Objekt konstruiert:

javax.xml.parsers.DocumentBuilderFactory dbf =
  javax.xml.parsers.DocumentBuilderFactory.newInstance( );
  javax.xml.parsers.DocumentBuilder docBuilder =
    dbf.newDocumentBuilder( );
  Document doc = docBuilder.newDocument( );

Dieser Code basiert auf JAXP, weil die normale DOM-API keine standardisierte Möglichkeit zur Erzeugung eines Document-Objekts bietet. Verschiedene Parser verfügen zwar über eigene proprietäre Methoden, das zu erledigen, genau das ist jedoch der Grund für den Einsatz von JAXP: Diese API kapselt die Unterschiede zwischen den verschiedenen XML-Parsern und erlaubt so Java-Programmierern die Verwendung einer konsistenten Schnittstelle, unabhängig vom eingesetzten Parser. Wie wir unter XSLT-Verarbeitung mit Java sehen werden, fügt JAXP 1.1 verschiedenen XSLT-Prozessoren einen konsistenten Wrapper hinzu, zusätzlich zu den Standard-SAX- und -DOM-Parsern.

JAXP kennt eine DocumentBuilderFactory-Klasse zur Konstruktion eines DocumentBuilder-Objekts, welches wiederum der Erzeugung von neuen Document-Objekten dient. Das Document-Interface ist Bestandteil von DOM, weswegen der größte Teil des übrigen Codes durch die DOM-Spezifikationen definiert ist.

Mit DOM müssen neue XML-Elemente immer mit speziellen Erzeugungsmethoden wie createElement(...) oder einer Instanz von Document generiert werden. Diese Elemente müssen dann entweder dem Dokument selbst oder einem seiner Elemente hinzugefügt werden, bevor sie Bestandteil des XML werden:

// erzeuge das <bibliothek>-Wurzelelement des Dokuments
Element root = doc.createElement("bibliothek");
doc.appendChild(root);

An dieser Stelle ist das <bibliothek/>-Element noch leer, aber es wurde dem Dokument hinzugefügt. Die Code-Ausführung schreitet fort und fügt alle <verlag>-Kindelemente hinzu:

// füge dem <bibliothek>-Element <verlag>-Kindelemente hinzu
Iterator verlagsIter = bibliothek.getVerlag().iterator();
while (verlagsIter.hasNext()) {
   Verlag verlag = (Verlag) verlagsIter.next();
   Element verlagElem = createVerlagElement(doc, verlag);
   root.appendChild(verlagElem);
}

Für jede Instanz von Verlag wird ein <Verlag>-Element erzeugt und dann der <bibliothek> hinzugefügt. Die Methode createVerlagElement ist eine private Hilfsmethode, die einem schlicht die mühselige Prozedur abnimmt, mit DOM ein XML-Element zu erzeugen. Nicht ganz offensichtlich mag die Art erscheinen, wie den Elementen Text hinzugefügt wird, also wie beispielsweise O’Reilly in das <name>O'Reilly</name>-Tag:

Element name = doc.createElement("name");
name.appendChild(doc.createTextNode(verlag.getName()));
verlagElem.appendChild(name);

Die erste Zeile ist noch gut nachvollziehbar, es wird nur ein leeres <name/>-Element erzeugt. Die nächste Zeile fügt dann, anstatt den Wert direkt dem Name-Objekt zuzuweisen, einen neuen, sogenannten Text-Node, also einen Textknoten als Kind des Name-Objekts hinzu. Das zeigt die Art, wie DOM XML darstellt: Alle geparsten Zeichen-Daten (PCDATA) werden als Kind eines Elements angesehen und nicht als Teil des Elements selbst. DOM verwendet die Schnittstelle org.w3c.dom.Text, die eine Erweiterung von org.w3c.dom.Node darstellt, um Textknoten darzustellen. Das ist oft ärgerlich, denn es resultiert in mindestens einer zusätzlichen Codezeile für jedes Element, das Sie erzeugen möchten.

Die main()-Methode im Beispiel XML-Erzeugung mit DOM erzeugt ein Bibliothek-Objekt, wandelt es in einen DOM-Baum und schreibt den XML-Text auf System.out. Weil die Standard-DOM-API keine Möglichkeit bietet, einen DOM-Baum in XML umzuwandeln, führen wir nun Xerces-spezifischen Code zur Konvertierung eines DOM-Baumes in die Textform ein:

// Schreibe das Dokument mit Apache Xerces
// gib das Dokument mit UTF-8-Kodierung aus; rücke jede Zeile ein
org.apache.xml.serialize.OutputFormat fmt =
  new org.apache.xml.serialize.OutputFormat(doc, "UTF-8", true);
org.apache.xml.serialize.XMLSerializer serial =
  new org.apache.xml.serialize.XMLSerializer(System.out, fmt);
serial.serialize(doc.getDocumentElement());

Wie wir unter XSLT-Verarbeitung mit Java noch sehen werden, kennt JAXP 1.1 einen Mechanismus, diese Aufgabe mit seinen Transformations-APIs durchzuführen. Daher muß der hier gezeigte Xerces-Code praktisch nicht verwendet werden. Die JAXP-Methode bietet zwar größtmögliche Portierbarkeit, bringt aber den Overhead eines XSLT-Prozessors in einen Code, wo eigentlich nur DOM gebraucht wird.

JDOM

DOM ist in der sprachunabhängigen CORBA IDL (Common Object Request Broker Architecture Interface Definition Language) spezifiziert, die die Nutzung der gleichen Schnittstellen und Konzepte in vielen verschiedenen Programmiersprachen ermöglicht. Obwohl das aus der Sicht einer Spezifikation wertvoll scheinen mag, nutzt diese Methode nicht die Vorteile spezifischer Merkmale von Java. JDOM ist eine reine Java-API, die für eine intuitivere Erzeugung und Modifikation von XML-Dokumenten verwendet werden kann. Unter Nutzung von Java-Merkmalen zielt JDOM auf die Vereinfachung der doch oft anstrengenden Aspekte der DOM-Programmierung.

JDOM ist keine W3C-Spezifikation, aber Open Source-Software. JDOM ist aus Programmierer-Sicht etwas Großartiges, denn es entsteht sauberer, besser zu wartender Code. Mit der Fähigkeit, seine Daten in einen Standard-DOM-Baum zu wandeln, integriert sich JDOM elegant in jedes andere XML-Tool. JDOM kann außerdem jeden XML-Parser verwenden und XML in jeden Java-Output-Stream oder jede Datei schreiben. Es enthält sogar eine Klasse SAXOutputter, die es erlaubt, die JDOM-Daten in jedes Tool zu integrieren, das SAX-Events erwartet.

Der Code im Beispiel XML-Erzeugung mit JDOM zeigt, um wieviel JDOM leichter ist als DOM; es macht dasselbe wie das DOM-Beipiel, nur mit etwa fünfzig Zeilen weniger Code. Dieser Unterschied wäre in komplexeren Anwendungen noch größer.

Beispiel: XML-Erzeugung mit JDOM

package com.oreilly.javaxslt.chap1;

import java.io.*;
import java.util.*;
import org.jdom.DocType;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

/**
* Ein Beispiel aus Kapitel 1. Es erzeugt die Bibliothek-XML-Datei.
*/
public class BibliothekJDOMCreator {
  
  public Document createDokument(Bibliothek bibliothek) {
    Element root = new Element("bibliothek");
    // JDOM unterstützt <!DOCTYPE...>
    DocType dt = new DocType("bibliothek", "bibliothek.dtd");
    Document doc = new Document(root, dt);
    
    // füge dem <bibliothek>-Element <verlag>-Kindelemente hinzu
    Iterator verlagsIter = bibliothek.getVerlage().iterator( );
    while (verlagsIter.hasNext( )) {
      Verlag verlag = (Verlag) verlagsIter.next( );
      Element verlagElem = createVerlagElement(verlag);
      root.addContent(verlagElem);
    }
    
    // nun füge dem <bibliothek>-Element <buch>-Kindelemente hinzu
    Iterator buchIter = bibliothek.getBuecher().iterator( );
    while (buchIter.hasNext( )) {
      Buch buch = (Buch) buchIter.next( );
      Element buchElem = createBuchElement(buch);
      root.addContent(buchElem);
    }
    
    return doc;
  }
  
  private Element createVerlagElement(Verlag verlag) {
    Element verlagElem = new Element("verlag");
    verlagElem.addAttribute("id", verlag.getId( ));
    verlagElem.addContent(new Element("name").setText(verlag.getName( )));
    verlagElem.addContent(new Element("strasse").setText(verlag.getStrasse( )));
    verlagElem.addContent(new Element("stadt").setText(verlag.getStadt( )));
    verlagElem.addContent(new Element("plz").setText(verlag.getPlz( )));
    
    return verlagElem;
  }
  
  private Element createBuchElement(Buch buch) {
    Element buchElem = new Element("buch");
    // Füge dem <buch>-Element die Attribute verlag und isbn
    // hinzu
    buchElem.addAttribute("verlag", buch.getVerlag().getId( ))
      .addAttribute("isbn", buch.getIsbn( ));
    
    // nun kommt das <ausgabe>-Element hinzu
    buchElem.addContent(new Element("ausgabe").setText(
      Integer.toString(buch.getAusgabe( ))));
    
    Element veroeffentlichungsDatum = new Element("veroeffentlichungsDatum");
    veroeffentlichungsDatum.addAttribute("mm",
      Integer.toString(buch.getVeroeffentlichungsMonat( )));
    veroeffentlichungsDatum.addAttribute("jj",
      Integer.toString(buch.getVeroeffentlichungsJahr( )));
    buchElem.addContent(veroeffentlichungsDatum);
    
    buchElem.addContent(new Element("titel").setText(buch.getTitel( )));
    buchElem.addContent(new Element("autor").setText(buch.getAutor( )));
    
    return buchElem;
  }
  
  public static void main(String [] args) throws IOException {
    Bibliothek bibl = new Bibliothek( );
    BibliothekJDOMCreator bjc = new BibliothekJDOMCreator( );
    Document doc = bjc.createDocument(bibl);
    
    // Schreibe das XML auf System.out, rücke um zwei Leerzeichen ein, füge
    // Zeilenwechsel hinter jedem Element hinzu
    new XMLOutputter(" ", true, "ISO-8859-1").output(doc, System.out);
  }
}  

Das JDOM-Beispiel ist genauso strukturiert wie das DOM-Beispiel. Es fängt mit einer Methode an, die das Bibliothek-Objekt in ein JDOM-Document umwandelt.

public Document createDocument(Bibliothek bibliothek) {

Der gewaltigste Unterschied in dieser speziellen Methode ist die Art, wie das Dokument und seine Elemente erzeugt werden. Mit JDOM erzeugt man einfach Java-Objekte, die Bestandteile von XML-Daten repräsentieren. Dies steht der DOM-Methode entgegen, die auf Schnittstellen und Factory-Methoden basiert. Das Erzeugen des Dokuments ist ebenfalls sehr leicht mit JDOM:

Element root = new Element("bibliothek");
// JDOM unterstützt <!DOCTYPE...>
DocType dt = new DocType("bibliothek", "bibliothek.dtd");
Document doc = new Document(root, dt);  

Wie der Kommentar andeutet, erlaubt JDOM im Gegensatz zu DOM, auf eine DTD zu verweisen. Das ist nur eine weitere Beschränkung von DOM, die Sie zwingt, implementierungsabhängigen Code in Ihren Java-Anwendungen zu verwenden. Ein anderer Bereich, in dem JDOM überzeugt, ist das Erzeugen neuer Elemente. Anders als bei DOM wird der Text unmittelbar in den Element-Objekten gesetzt, was für Java-Programmierer wesentlich intuitiver ist:

private Element createVerlagElement(Verlag verlag) {
  Element verlagElem = new Element("verlag");
  
  verlagElem.addAttribute("id", verlag.getId());
  verlagElem.addContent(new Element("name").setText(verlag.getName()));
  verlagElem.addContent(new Element("strasse").setText(verlag.getStrasse()));
  verlagElem.addContent(new Element("stadt").setText(verlag.getStadt()));
  verlagElem.addContent(new Element("plz").setText(verlag.getPlz()));
  
  return verlagElem;
}

Da Methoden wie addContent( ) und addAttribute( ) eine Referenz auf die Element-Instanz zurückliefern, hätte der gezeigte Code auch in einer langen Zeile geschrieben werden können, ähnlich wie bei der Methode StringBuffer.append(), die auch so »verkettet« werden kann:

buf.append("a").append("b").append("c");

Um den JDOM-Code lesbar zu halten, wird in unserem Beispiel aber pro Zeile ein Element hinzugefügt.

Das letzte Stück Code dient nun dazu, die JDOM-Inhalte als XML-Datei auszugeben. JDOM beinhaltet eine Klasse XMLOutputter, die uns ermöglicht, die XML-Ausgabe für ein Document-Objekt mit einer einzigen Zeile Code vorzunehmen:

new XMLOutputter(" ", true, "ISO-8859-1").output(doc, System.out);

Die drei an XMLOutputter übergebenen Parameter geben an, daß zwei Leerzeichen für die Einrückungen verwendet werden sollen, Zeilenvorschübe gemacht werden sollen und die Ausgabe UTF-8-kodiert werden soll.

Zusammenarbeit zwischen JDOM und DOM

Die gegenwärtig verfügbaren XSLT-Prozessoren sind sehr flexibel und unterstützen generell jede der folgenden Quellen für die XML- oder XSLT-Eingabe:

  • ein DOM-Baum oder die Ausgabe eines SAX-Parsers
  • jeden Java-InputStream oder -Reader
  • einen URI, Dateinamen oder ein java.io.File-Objekt

JDOM wird von manchen XSLT-Prozessoren nicht unmittelbar unterstützt, obwohl sich das schon bald ändern wird. (Anmerkung: Bei Drucklegung wurde Version 6.4 von SAXON veröffentlicht. Diese Version hat Beta-Support für die Transformation von JDOM-Bäumen. Zusätzlich führt JDOM Beta 7 zwei neue Klassen ein, JDOMSource und JDOMResult, die mit jedem JAXP-konformen XSLT-Prozessor zusammenarbeiten.) Daher wandelt man typischerweise eine JDOM-Document-Instanz in ein anderes Format um, damit sie von einem XSLT-Prozessor verarbeitet werden kann. Glücklicherweise bietet das JDOM-Paket eine Klasse DOMOutputter, die diese Transformation sehr leicht durchführen kann:

org.jdom.output.DOMOutputter outputter =
     new org.jdom.output.DOMOutputter( );
org.w3c.dom.Document domDocument = outputter.output(jdomDocument);

Dieses DOM Document-Objekt kann dann mit jedem XSLT-Prozessor und einer ganzen Heerschar von anderen XML-Bibliotheken und -Tools bearbeitet werden. JDOM beinhaltet auch eine Klasse, die ein Document-Objekt in eine Reihe von SAX-Events wandeln kann, und eine andere Klasse, die XML-Daten an ein OutputStream- oder Writer-Objekt senden kann. Ziemlich bald, so sieht es jedenfalls aus, werden viele Tools JDOM-Unterstützung anbieten, so daß zusätzliche Umwandlungen entfallen können.

   

zum Seitenanfang

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Java & XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2002 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Java und XSLT" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de