![]() |
|
|||||
13.4.5 Das Dokument als XML-Datei ausgeben
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Beispiel Ein gültiger Dokumenttyp für XHTML-Dateien hat folgendes Format:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
Bearbeiten wir dies über JDOM, so liefert die Methode getDocType() vom Dokument-Objekt ein DocType-Objekt, welches wir nach den IDs fragen können. Über setDocType() kann der veränderte Dokumenttyp neu zugewiesen werden.
class org.jdom.Document |
| DocType getDocType() Liefert das zugehörige DocType-Objekt oder null, wenn keines existiert. |
| Document setDocType( DocType docType ) Setzt ein neues DocType-Objekt für das Dokument. |
Beispiel Wir erfragen vom Dokument den Elementnamen, die öffentliche ID und die System-ID.
DocType docType = doc.getDocType(); System.out.println( "Element: " + docType.getElementName() ); System.out.println( "Public ID: " + docType.getPublicID() ); System.out.println( "System ID: " + docType.getSystemID() ); |
Zu den Methoden getPublicID() und getSystemID() gibt es entsprechende Setze-Methoden, nicht aber für den Elementnamen, dieser kann nachträglich nicht mehr modifiziert werden. Wir müssten dann ein neues DocTyp-Objekt anlegen. Es gibt mehrere Varianten von Konstruktoren, mit denen gesteuert werden kann, welche Einträge gesetzt werden.
Beispiel Wir legen ein neues DocType-Objekt an und weisen es einem Dokument doc zu.
DocType doctype = new DocType( "html", "-//W3C...", "http://..." ) ; doc.setDocType( doctype ); |
Jedes Dokument besteht aus einem Wurzelelement. Wir haben schon gesehen, dass dies durch die Klasse Element abgebildet wird. Mit dem Wurzelelement gelingt der Zugriff auf die anderen Elemente des Dokumentenbaums.
Im Folgenden wird die Beispieldatei party.xml verwendet, um die Funktionen von JDOM vorzustellen. Durch das Erzeugen eines leeren JDOM-Dokuments und die Methoden zum Erzeugen von Elementen und Attributen kann diese Datei auch leicht mit JDOM erzeugt werden.
Beispiel Die Datei party.xml hat folgendes Format:
party.xml <party datum=“31.12.01“> <gast name="Albert Angsthase"> <getraenk>Wein</getraenk> <getraenk>Bier</getraenk> <zustand ledig=“true“ nuechtern=“false“/> </gast> <gast name="Martina Mutig"> <getraenk>Apfelsaft</getraenk> <zustand ledig=“true“ nuechtern=“true“/> </gast> <gast name="Zacharias Zottelig"></gast> </party> |
Um an das Wurzelelement <party> zu kommen und von dort aus weitere Elemente oder Attribute auslesen zu können, schreiben wir:
//Erzeugen eines JDOM-Dokuments anhand der Datei party.xml SAXBuilder builder = new SAXBuilder(); Document doc = builder.build( "party.xml" ); //Lesen des Wurzelelements des JDOM-Dokuments doc Element party = doc.getRootElement();
class org.jdom.Document |
| Element getRootElement() Gibt das Root-Element zurück oder null, falls kein Root-Element vorhanden ist. |
| boolean isRootElement() Rückgabe eines Wahrheitswerts, der ausdrückt, ob das Element die Wurzel der JDOM-Datenstruktur ist. |
Durch die oben gezeigten Anweisungen wird aus der XML-Datei party.xml eine JDOM-Datenstruktur im Speicher erzeugt. Um mit dem Inhalt der XML-Datei arbeiten zu können, ist der Zugriff auf die einzelnen Elemente notwendig. Durch die Methode getRoot Element() wird das Wurzelelement der XML-Datei zurückgegeben. Dieses Element ist der Ausgangspunkt für die weitere Verarbeitung der Datei.
Um ein bestimmtes Element zu erhalten, gibt es die Methode getChild(String name). Mit dieser Methode wird das nächste Unterelement des Elements, das diesen Namen trägt, zurückgegeben. Eine Liste mit allen Elementen liefert die Methode getChildren(). Sie gibt eine Liste mit allen Elementen mit diesem Namen zurück:
org.jdom.Element |
| Element getChild( String name ) Rückgabe des ersten untergeordneten Elements mit dem lokalen Namen name, das keinem Namensraum zugeordnet ist. |
| Element getChild( String name, Namespace ns ) Rückgabe des ersten untergeordneten Elements mit dem lokalen Namen name, das dem Namensraum ns zugeordnet ist. |
| List getChildren() Rückgabe einer Liste der Elemente, die diesem Element direkt untergeordnet sind. Falls keine Elemente existieren wird eine leere Liste zurückgegeben. Änderungen an der Liste spiegeln sich auch in der JDOM-Datenstruktur wieder. |
| List getChildren( String name ) Rückgabe einer Liste der Elemente mit dem Namen name, die diesem Element direkt untergeordnet sind. Falls keine Elemente existieren, wird eine leere Liste zurückgegeben. Änderungen an der Liste spiegeln sich auch in der JDOM-Datenstruktur wider. |
| List getChildren( String name, Namespace ns ) Rückgabe einer Liste der Elemente mit dem Namen name, die diesem Namensraum zugeordnet und diesem Element direkt untergeordnet sind. Falls keine Elemente existieren, wird eine leere Liste zurückgegeben. Änderungen an der Liste spiegeln sich auch in der JDOM-Datenstruktur wider. |
| boolean hasChildren() Rückgabe eines boolean-Werts, der ausdrückt, ob Elemente untergeordnet sind oder nicht. |
Beispiel Wenn wir den ersten Gast auf der Party haben möchten, schreiben wir:
Element party = doc.getRootElement(); Element albert = party.getChild( "gast" ); Wenn wir wissen wollen, was Albert trinkt: Element albertGetraenk = albert.getChild( "getraenk" ); Es ist aber auch möglich, über das Wurzelelement auf das Getränk des ersten Gastes zuzugreifen: Element albertGetraenk = party.getChild( "gast" ).getChild( "getraenk" ); Falls wir eine Gästeliste der Party haben wollen, schreiben wir: List gaeste = party.getChildren( "gast" ); Diese Liste enthält alle Elemente der Form <gast ...> ... </gast>, die direkt unter dem Element <party> liegen. Diese Liste ist eine Java-Collection und kann mit den Anweisungen für Collections weiterverarbeitet werden. Dadurch ist es möglich, mit einem Iterator die Liste zu durchlaufen, um einzelne Elemente zu verarbeiten. |
Von Beginn eines Elements bis zu dessen Ende treffen wir auf drei unterschiedliche Informationen:
| Es können weitere Elemente folgen. Im oberen Beispiel folgt in <gast> noch ein Element <getraenk>. |
| Das Element enthält Text (wie das Element <getraenk>). |
| Zusätzlich kann ein Element auch Attribute beinhalten. Dies haben wir auch beim Element <gast> gesehen, das als Attribut den Namen des Gasts enthält. Der Inhalt von Attributen ist immer Text. |
Für diese Aufgaben bietet die Element-Klasse unterschiedliche Anfrage- und Setze-Methoden. Wir wollen mit dem Einfachsten, dem Zugriff auf den Textinhalt eines Elements, beginnen.
Betrachten wir das Element, dessen Inhalt wir auslesen wollen, so nutzen wir dazu die Methode getText().
<getraenk>Wein</getraenk>
Sie liefert einen String, sofern eine String-Repräsentation des Inhalts erlaubt ist. Falls das Element keinen Text oder nur Unterelemente besitzt, so ist der Rückgabewert ein Leerstring.
Um an das erste Getränk von Albert zu kommen, schreiben wir:
Element party = doc.getRootElement(); Element albertGetraenk = party.getChild( "gast" ).getChild( "getraenk" ); String getraenk = albertGetraenk.getText();
class org.jdom.Element |
| String getText() Rückgabe des Inhalts des Elements. Dies beinhaltet alle Leerzeichen und CDATA-Sektionen. Falls der Elementinhalt nicht zurückgeben werden kann, wird der leere String zurückgeben. |
| String getTextNormalize() Verhält sich wie getText(). Leerzeichen am Anfang und am Ende des Strings werden entfernt. Leerzeichen innerhalb des Strings werden auf ein Leerzeichen normalisiert. Falls der Text nur aus Leerzeichen besteht, wird der leere String zurückgegeben. |
| String getTextTrim() Verhält sich wie getTextNormalize(). Leerzeichen innerhalb des Strings bleiben erhalten. |
Für die Methode getText() muss das Element vorliegen, dessen Inhalt gelesen werden soll. Mit der Methode getChildText() kann auch direkt der Inhalt eines untergeordneten Elements ermittelt werden. Das folgende Beispiel liest den Text des ersten untergeordneten Elements mit dem Namen getraenk. Das übergeordnete Element von Getränk ist albert:
Element albert = party.getChild( "gast" ); String getraenk = albert.getChildText( "getraenk" );
In der Implementierung der Methode getChildText() sind die Methoden getChild() und getText() zusammengefasst.
| class org.jdom.Element |
| String getChildText( String name ) Rückgabe des Inhalts des Elements mit dem Namen name. Falls der Inhalt kein Text ist, wird ein leerer String zurückgegeben. Falls das Element nicht existiert, wird null zurückgegeben. |
| String getChildText( String name, Namespace ns ) Verhält sich wie getChildText(String) im Namensraum ns. |
| String getChildTextTrim( String name ) Verhält sich wie getChildText(String). Leerzeichen am Anfang und am Ende des Strings werden entfernt. Leerzeichen innerhalb des Strings bleiben erhalten. |
| String getChildTextTrim( String name, Namespace ns ) Verhält sich wie getChildTextTrim(String) im Namensraum ns. |
| String getName() Rückgabe des lokalen Namens des Elements ohne Namensraumpräfix. |
| Namespace getNamespace() Rückgabe des Namensraums oder eines leeren Strings, falls diesem Element kein Namensraum zugeordnet ist. |
| Namespace getNamespace( String prefix ) Rückgabe des Namensraums des Elements mit diesem Präfix. Dies beinhaltet das Hochlaufen in der Hierarchie des JDOM-Dokuments. Falls kein Namensraum gefunden wird, gibt diese Methode null zurück. |
| String getNamespacePrefix() Rückgabe des Namensraumpräfix. Falls kein Namensraumpräfix existiert, wird ein Leerstring zurückgegeben. |
| String getNamespaceURI() Rückgabe der Namensraum-URI, die dem Präfix dieses Elements zugeordnet ist, oder des Standard-Namensraums. Falls keine URI gefunden werden kann, wird ein leerer String zurückgegeben. |
Mit den oben beschriebenen Methoden war es bislang immer nur möglich, das erste untergeordnete Element mit einem bestimmten Namen zu lesen. Um gezielt nach bestimmten Elementen zu suchen, ist es notwendig, die untergeordneten Elemente in eine Liste zu übertragen. Mit der Methode getContent() wird eine Liste mit allen Elementen und Unterelementen erzeugt. Diese Liste enthält Referenzen der Elemente aus der JDOM-Datenstruktur.
Beispiel Hole eine Liste aller Informationen der Party.
Element party = doc.getRootElement(); List partyInfo = party.getContent(); |
Mit einem Iterator kann diese Liste durchlaufen werden.
Beispiel Einen Iterator aus der Liste partyInfo erzeugen und die Liste durchlaufen.
Iterator partyIterator = partyInfo.iterator(); while ( partyIterator.hasNext() ) |
{ System.out.println( partyIterator.next().toString() ); } |
class org.jdom.Element |
| List getContent() Dies liefert den vollständigen Inhalt eines Elements mit allen Unterelementen. Die Liste kann Objekte vom Typ String, Element, Comment, ProcessingInstruction und Entity enthalten. Falls keine Elemente vorhanden sind, wird eine leere Liste zurückgegeben. |
Um neue Elemente zu erzeugen, bietet die Klasse Element unter anderem den Konstruktor Element(String) an. Es wird ein Element mit dem entsprechenden Namen erzeugt.
Beispiel Wir erzeugen eine Liste mit allen Unterelementen von albert, erzeugen ein neues Element und fügen dies in die Liste ein.
Element party = doc.getRootElement(); Element albert = party.getChild( "gast" ); |
List albertInfo = albert.getContent(); Element wasser = new Element( "getraenk" ); wasser.addContent( "Wasser" ); |
Um den Wert eines Elements zu ändern, gibt es die Methoden setText() und addContent(). Die Methode setText() hat allerdings die unangenehme Eigenschaft, alle Unterelemente zu entfernen. Die Methode addContent() fügt neuen Inhalt hinzu.
Wenn der Inhalt eines Elements ausgetauscht werden soll, muss der alte entfernt und der neue Inhalt mit addContent() hinzugefügt werden. Die Methode addContent() kann nicht nur Text, sondern jeden beliebigen Inhalt einfügen.
| Beispiel Albert will in Zukunft keinen Wein mehr trinken, sondern nur noch Wasser und Bier. |
Zuerst wird das erste Unterelement gelöscht:
albert.removeChild( "getraenk" );
Ein neues Element wasser wird erzeugt und mit Inhalt gefüllt:
Element wasser = new Element( "getraenk" ); wasser.addContent( "Wasser" );
Das neue Element wird dem Element albert untergeordnet:
albert.addContent( wasser );
Werfen wir erneut einen Blick auf unsere XML-Datei und entfernen das erste Element <getraenk>, das dem ersten Element <gast> untergeordnet ist.
<party datum=“31.12.01“> <gast name="Albert Angsthase"> <getraenk>Wein</getraenk> <getraenk>Bier</getraenk> <zustand ledig=“true“ nuechtern=“false“/> </gast> <party>
Beispiel Die Funktion entfernt das Element <getraenk>.
Element party = doc.getRootElement(); Element albert = party.getChild( "gast" ); // Es werden nur die direkten Nachfolger durchsucht. Diese Funktion // findet das Element <getraenk>Wein</getraenk> nicht. party.removeChild("getraenk"); // Mit dieser Funktion wird das Element // <getraenk>Wein</getraenk> gelöscht. albert.removeChild("getraenk"); |
| class org.jdom.Element |
| Element( String name ) Dieser Konstruktor erzeugt ein Element mit dem Namen name, ohne Zuordnung zu einem Namensraum. |
| Element( String name, Namespace namespace ) Dieser Konstruktor erzeugt ein Element mit dem Namen name und dem Namensraum namespace. |
| Element( String name, String uri ) Dieser Konstruktor erzeugt ein neues Element mit dem lokalen Namen name und der URI des Namensraums, der zu dem Element ohne Präfix gehört. |
| Element( String name, String prefix, String uri ) Dieser Konstruktor erzeugt ein neues Element mit dem lokalen Namen name, dem Namenspräfix prefix und der URI des Namensraums. |
| boolean removeChild( String name ) Entfernt das erste gefundene Unterelement mit den Namen name, das gefunden wird und keinem Namensraum zugeordnet ist. Es werden nur die direkten Nachfolger durchsucht. |
| boolean removeChild( String name, Namespace ns) Verhält sich wie removeChild(String name). Der Namensraum wird bei der Auswahl des Elements berücksichtigt. |
| boolean removeChildren() Entfernt alle untergeordneten Elemente. |
| boolean removeChildren( String name ) Entfernt alle Unterelemente mit den Namen name, die gefunden werden und keinem Namensraum zugeordnet sind. Es werden nur die direkten Nachfolger durchsucht. |
| boolean removeChildren( String name, Namespace ns ) Verhält sich wie removeChildren(String) im Namensraum ns. |
Bei den folgenden Methoden wird als Rückgabewert das geänderte Element zurückgegeben:
| Element setText( String text ) Setzt den Inhalt des Elements. Alle anderen Inhalte und alle Unterelemente werden gelöscht. |
| Element addContent( String text ) Ergänzt den Inhalt des Elements um den Text. |
| Element addContent( Element element ) Ergänzt den Inhalt des Elements um das Element als Unterelement. |
| Element addContent( ProcessingInstruction pi ) Ergänzt den Inhalt des Elements um die Processing Instruction pi. |
| Element addContent( EntityRef entität ) Ergänzt den Inhalt des Elements um die Entität. |
| Element addContent( CDATA cdata ) Ergänzt den Inhalt des Elements um eine CDATA-Sektion. |
| Element addContent( Comment comment ) Ergänzt den Inhalt des Elements um einen Kommentar. |
| Element getCopy( String name ) Erzeugt eine Kopie des Elements mit dem neuen Namen name, ohne Zuordnung zu einem Namensraum. |
| Element getCopy( String name, Namespace ns ) Erzeugt eine Kopie des Elements mit dem neuem Namen name und eine Zuordnung zu dem Namensraum ns. |
| Document getDocument() Liefert das Dokument dieses Elements, null, falls das Element keinem Dokument zugeordnet ist. |
Ein Element kann auch einen Attributwert enthalten. Dies ist der Wert, der direkt in dem Tag mit angegeben ist. Betrachten wir dazu folgendes Element:
<gast name="Albert Angsthase">
Das Element hat als Attribut name="Albert Angsthase". Dieser Wert kann mit der Methode getAttribute(String).getValue() der Klasse Element gelesen werden. In diesem Fall wird mit getAttribute( "name" ).getValue() der Attributwert von dem Element albert gelesen.
Beispiel Lesen des Namens
Element party = doc.getRootElement(); Element albert = party.getChild( "gast" ); String albertName = albert.getAttribute( "name" ); |
Genauso kann auch der Wert eines Attributs geschrieben werden. Dazu gibt es die Methoden setAttribute(String) der Klasse Attribute und addAttribute(Attribute) der Klasse Element. Es gibt eine Klasse Attribute, mit deren Hilfe das Modellieren von Attributen mit Java ermöglicht wird.
Wollen wir den Namen von Albert wissen, schreiben wir:
String albertName = albert.getAttribute( "name" ).getValue();
Wenn Martina wissen möchte, ob Albert noch ledig ist:
albert.getChild( "zustand" ).getAttribute( "ledig" ).getValue();
Martina und Albert haben geheiratet, und Albert nimmt den Namen von Martina an:
albert.getAttribute( "name" ).setAttribute( "Albert Mutig" );
Seit der Hochzeit mit Albert trinkt Martina auch Wein. Also muss ein neues Element wein unter dem Element <gast name="Martina Mutig"> eingefügt werden. Zuerst erzeugen wir ein Element der Form <getraenk>Wein</getraenk>.
Element wein = new Element( "getraenk" ); wein.addContent( "Wein" );
Danach suchen wir Martina in der Gästeliste und fügen das Element <wein> ein:
// Liste aller Gäste Iterator gaesteListe = party.getChildren( "gast" ).iterator(); while ( gaesteListe.hasNext() ) { Element gast = (Element)gaesteListe.next(); if ( "Martina Mutig".equals( gast.getAttribute( "name" ).getValue()) ) gast.addContent( wein ); }
An diesem Beispiel wird deutlich, wie flexibel die Methode addContent(Inhalt) ist. Es zeigt ebenso, wie JDOM für Java, etwa durch die Implementierung der Schnittstelle List, optimiert wurde.
| class org.jdom.Element |
| Attribute getAttribute( String name ) |
| Attribute getAttribute( String name, Namespace ns ) |
| List getAttributes() |
| String getAttributeValue( String name ) |
| String getAttributeValue( String name, Namespace ns ) |
| Element setAttributes( List attributes ) |
| Element addAttribute(Attribute attribute) |
| Element addAttribute( String name, String value ) Einfügen des Attributs mit dem Namen name und dem Wert value. Um Attribute mit einem Namensraum hinzuzufügen, sollte man die Methode addAttribute(Attribute attribute) verwenden. |
| class org.jdom.Attribute |
| String getValue() Rückgabe des Werts dieses Attributs. |
Die folgenden Methoden versuchen eine Umwandlung in einen primitiven Datentyp. Falls eine Umwandlung nicht möglich ist, wird eine DataConversionException ausgelöst.
| getBooleanValue() Gibt den Wert des Attributs als boolean zurück. |
| double getDoubleValue() Gibt den Wert des Attributs als double zurück. |
| float getFloatValue() Gibt den Wert des Attributs als float zurück. |
| int getIntValue() Gibt den Wert des Attributs als int zurück. |
| long getLongValue() Gibt den Wert des Attributs als long zurück. |
| String getName() Gibt den lokalen Namen des Attributs zurück. Falls der Name die Form [namespacePrefix]:[elementName] hat, wird [elementName] zurückgegeben. Wenn der Name kein Namensraumpräfix hat, wird einfach nur der Name ausgegeben. |
| Namespace getNamespace() Gibt den Namensraum des Attributs zurück. Falls kein Namensraum vorhanden ist, wird das konstante Namensraum-Objekt NO_NAMESPACE zurückgegeben. Diese Konstante enthält ein Namensraum-Objekt mit dem leeren String als Namensraum. |
| String getNamespacePrefix() Gibt das Präfix des Namensraums zurück. Falls kein Namensraum zugeordnet ist, wird ein leerer String zurückgegeben. |
| String getNamespaceURI() Gibt die URI zurück, die zu dem Namensraum dieses Elements gehört. Falls kein Namensraum zugeordnet ist, wird ein leerer String zurückgegeben. |
| Element getParent() Gibt das Element zurück, das dem Element dieses Attributs übergeordnet ist. Falls kein übergeordnetes Element vorhanden ist, wird null zurückgegeben. |
| String getQualifiedName() Rückgabe des qualifizierten Namens des Attributs. Falls der Name die Form [namespacePrefix]:[elementName] hat, wird dies zurückgegeben. Ansonsten wird der lokale Name zurückgegeben. |
| getSerializedForm() Rückgabe des Attributs im XML-Format. |
| Attribute setValue( String value ) Setzt den Wert dieses Attributs. |
| << zurück |
Copyright © Galileo Press GmbH 2003
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> 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.