Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Neues in Java 7
2 Threads und nebenläufige Programmierung
3 Datenstrukturen und Algorithmen
4 Raum und Zeit
5 Dateien, Verzeichnisse und Dateizugriffe
6 Datenströme
7 Die eXtensible Markup Language (XML)
8 Dateiformate
9 Grafische Oberflächen mit Swing
10 Grafikprogrammierung
11 Netzwerkprogrammierung
12 Verteilte Programmierung mit RMI
13 RESTful und SOAP Web-Services
14 JavaServer Pages und Servlets
15 Applets
16 Datenbankmanagement mit JDBC
17 Technologien für die Infrastruktur
18 Reflection und Annotationen
19 Dynamische Übersetzung und Skriptsprachen
20 Logging und Monitoring
21 Java Native Interface (JNI)
22 Sicherheitskonzepte
23 Dienstprogramme für die Java-Umgebung
Stichwort
Download: - openbook, ca. 21,3 MB
Buch bestellen
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> / Java 7 - Mehr als eine Insel | vor >>
Java 7 - Mehr als eine Insel von Christian Ullenboom Das Handbuch zu den Java SE-Bibliotheken
Java 7 - Mehr als eine Insel Galileo Computing 1433 S., 2012, geb. 49,90 Euro, ISBN 978-3-8362-1507-7 |
| 7 Die eXtensible Markup Language (XML)
|  | 7.1 Auszeichnungssprachen
|  |  | 7.1.1 Die Standard Generalized Markup Language (SGML)
|  |  | 7.1.2 Extensible Markup Language (XML)
|  | 7.2 Eigenschaften von XML-Dokumenten
|  |  | 7.2.1 Elemente und Attribute
|  |  | 7.2.2 Beschreibungssprache für den Aufbau von XML-Dokumenten
|  |  | 7.2.3 Schema – eine Alternative zu DTD
|  |  | 7.2.4 Namensraum (Namespace)
|  |  | 7.2.5 XML-Applikationen *
|  | 7.3 Die Java-APIs für XML
|  |  | 7.3.1 Das Document Object Model (DOM)
|  |  | 7.3.2 Simple API for XML Parsing (SAX)
|  |  | 7.3.3 Pull-API StAX
|  |  | 7.3.4 Java Document Object Model (JDOM)
|  |  | 7.3.5 JAXP als Java-Schnittstelle zu XML
|  |  | 7.3.6 DOM-Bäume einlesen mit JAXP *
|  | 7.4 Java Architecture for XML Binding (JAXB)
|  |  | 7.4.1 Bean für JAXB aufbauen
|  |  | 7.4.2 JAXBContext und die Marshaller
|  |  | 7.4.3 Ganze Objektgraphen schreiben und lesen
|  |  | 7.4.4 Validierung
|  |  | 7.4.5 Weitere JAXB-Annotationen *
|  |  | 7.4.6 Beans aus XML-Schema-Datei generieren
|  | 7.5 Serielle Verarbeitung mit StAX
|  |  | 7.5.1 Unterschiede der Verarbeitungsmodelle
|  |  | 7.5.2 XML-Dateien mit dem Cursor-Verfahren lesen
|  |  | 7.5.3 XML-Dateien mit dem Iterator-Verfahren verarbeiten *
|  |  | 7.5.4 Mit Filtern arbeiten *
|  |  | 7.5.5 XML-Dokumente schreiben
|  | 7.6 Serielle Verarbeitung von XML mit SAX *
|  |  | 7.6.1 Schnittstellen von SAX
|  |  | 7.6.2 SAX-Parser erzeugen
|  |  | 7.6.3 Operationen der Schnittstelle ContentHandler
|  |  | 7.6.4 ErrorHandler und EntityResolver
|  | 7.7 XML-Dateien mit JDOM verarbeiten
|  |  | 7.7.1 JDOM beziehen
|  |  | 7.7.2 Paketübersicht *
|  |  | 7.7.3 Die Document-Klasse
|  |  | 7.7.4 Eingaben aus der Datei lesen
|  |  | 7.7.5 Das Dokument im XML-Format ausgeben
|  |  | 7.7.6 Der Dokumenttyp *
|  |  | 7.7.7 Elemente
|  |  | 7.7.8 Zugriff auf Elementinhalte
|  |  | 7.7.9 Liste mit Unterelementen erzeugen *
|  |  | 7.7.10 Neue Elemente einfügen und ändern
|  |  | 7.7.11 Attributinhalte lesen und ändern
|  |  | 7.7.12 XPath
|  | 7.8 Transformationen mit XSLT *
|  |  | 7.8.1 Templates und XPath als Kernelemente von XSLT
|  |  | 7.8.2 Umwandlung von XML-Dateien mit JDOM und JAXP
|  | 7.9 XML-Schema-Validierung *
|  |  | 7.9.1 SchemaFactory und Schema
|  |  | 7.9.2 Validator
|  |  | 7.9.3 Validierung unterschiedlicher Datenquellen durchführen
|  | 7.10 Zum Weiterlesen
## 7.7 XML-Dateien mit JDOM verarbeiten Über JDOM lassen sich die XML-formatierten Dateien einlesen, manipulieren und dann wieder schreiben. Mit einfachen Aufrufen lässt sich ein Dokument im Speicher erstellen. Zur internen JDOM-Repräsentation werden einige Java-typische Features verwendet, beispielsweise die Collection-API zur Speicherung, Reflection oder schwache Referenzen. Die Nutzung der Collection-API ist ein Vorteil, der unter dem herkömmlichen DOM nicht zum Tragen kommt. Durch JDOM können mit dem new-Operator auch Elemente und Attribute einfach erzeugt werden. Es gibt spezielle Klassen für das Dokument, nämlich Elemente, Attribute und Kommentare. Es sind keine Fabrikschnittstellen, die konfiguriert werden müssen, sondern alles wird direkt erzeugt. Die Modelle StAX, SAX oder DOM liegen eine Ebene unter JDOM, denn sie dienen als Ausgangspunkt zum Aufbau eines JDOM-Baums. Das heißt, dass ein vorgeschalteter SAX- oder StAX-Parser (bei JDOM Builder genannt) die JDOM-Baumstruktur im Speicher erzeugt. Die Bibliothek bietet daher eine neutrale Schnittstelle für diverse Parser, um die Verarbeitung der XML-Daten so unabhängig wie möglich von den Implementierungen zu machen. JDOM unterstützt dabei aktuelle Standards wie DOM Level 3, SAX 2.0 oder XML Schema. Wenn es nötig wird, DOM oder SAX zu unterstützen, bieten Schnittstellen diesen Einstieg an. Mit JDOM wird auch eine interne Datenstruktur der XML-Datei erzeugt. Dadurch kann jederzeit auf alle Elemente der XML-Datei zugegriffen werden. Da JDOM Java-spezifische Datenstrukturen verwendet, ist die Verarbeitung effizienter als bei DOM. JDOM stellt eine echte Alternative zu DOM dar. Eine Zusammenarbeit von JDOM und SAX ist auch möglich, weil JDOM in der Lage ist, als Ausgabe SAX-Ereignisse auszulösen. Diese können mit SAX-basierten Tools weiterverarbeitet werden. So lässt sich JDOM auch sehr gut in Umgebungen einsetzen, in denen weitere Tools zur Verarbeitung von XML genutzt werden. ### 7.7.1 JDOM beziehen Die Webseite http://www.jdom.org/ bietet Download, Dokumentation und Mailinglisten. Das Zip-Archiv http://jdom.org/dist/binary/jdom-1.1.1.zip enthält im build-Ordner die Datei jdom.jar, die wir dem Klassenpfad hinzufügen. Die API-Dokumentation liegt online unter http://jdom.org/docs/apidocs/index.html. JDOM ist freie Software, die auf der Apache-Lizenz beruht. Das heißt, dass JDOM auch in kommerziellen Produkten eingesetzt werden kann, ohne dass diese automatisch Open Source sein müssen. ### 7.7.2 Paketübersicht * JDOM besteht aus sieben Paketen mit den Klassen zur Repräsentation des Dokuments, zum Einlesen und Ausgeben, zur Transformation und für XPath-Anfragen. #### Das Paket org.jdom Das Paket org.jdom fasst alle Klassen zusammen, um ein XML-Dokument im Speicher zu repräsentieren. Dazu gehören zum Beispiel die Klassen Attribute, Comment, CDATA, DocType, Document, Element, Entity und ProcessingInstruction. Ein Dokument-Objekt hat ein Wurzelelement, eventuell Kommentare, einen DocType und eine ProcessingInstruction. Content ist die abstrakte Basisklasse und Oberklasse von Comment, DocType, Element, EntityRef, ProcessingInstruction und Text. Die Schnittstelle Parent implementieren alle Klassen, die Content haben können. Viele Schnittstellen gibt es in JDOM nicht. Andere XML-APIs verfolgen bei dieser Frage andere Ansätze; domj4 definiert zentrale Elemente als Schnittstellen, und die pure DOM-API beschreibt alles über Schnittstellen – konkrete Objekte kommen nur aus Fabriken, und die Implementierung ist unsichtbar. #### Die Pakete org.jdom.output und org.jdom.input In den beiden Paketen org.jdom.output und org.jdom.input liegen die Klassen, die XML-Dateien lesen und schreiben können. XMLOutputter übernimmt die interne Repräsentation und erzeugt eine XML-Ausgabe in einen PrintWriter. Daneben werden die unterschiedlichen Verarbeitungsstrategien DOM und SAX durch die Ausgabeklassen SAXOutputter und DOMOutputter berücksichtigt. SAXOutputter nimmt einen JDOM-Baum und erzeugt benutzerdefinierte SAX2-Ereignisse. Der SAXOutputter ist eine sehr einfache Klasse und bietet lediglich eine output(Document)-Methode an. Mit DOMOutputter wird aus dem internen Baum ein DOM-Baum erstellt. Ein Builder nimmt XML-Daten in verschiedenen Formaten entgegen und erzeugt daraus ein JDOM-Document-Objekt. Das ist bei JDOM der wirkliche Verdienst, dass unabhängig von der Eingabeverarbeitung ein API-Set zur Verfügung steht. Die verschiedenen DOM-Implementierungen unterscheiden sich an manchen Stellen. Die Schnittstelle Builder wird von allen einlesenden Klassen implementiert. Im Input-Paket befinden sich dafür die Klassen DOMBuilder, die einen JDOM-Baum mit DOM erzeugt, und SAXBuilder, die dafür SAX verwendet. Damit kann das Dokument aus einer Datei, einem Stream oder einer URL erzeugt werden. Nach dem Einlesen sind die Daten vom konkreten Parser des Herstellers unabhängig und können weiterverarbeitet werden. SAXBuilder ist schneller und speicherschonender. Ein DOMBuilder wird meistens nur dann benutzt, wenn ein DOM-Baum weiterverarbeitet werden soll. org.jdom.input.StAXBuilder ist eine Klasse aus dem Hilfspaket unter http://tutego.de/go/staxmisc. Im org.jdom.contrib-Package gibt es noch einige Erweiterungen für JDOM. Eine bemerkenswerte Erweiterung ist der ResultSetBuilder. Diese Klasse ermöglicht das Erstellen einer JDOM-Datenstruktur anhand eines java.sql.ResultSet. Dadurch ist eine Brücke zwischen Datenbanken und XML sehr einfach zu realisieren. Diese und noch viele weitere nützliche Erweiterungen sind nicht in der JDOM-Standarddistribution enthalten, sondern im Contrib-Paket. #### Das Paket org.jdom.transform Mit dem Paket org.jdom.transform wird das JAXP-TraX-Modell in JDOM integriert. Dies ermöglicht es JDOM, XSLT-Transformationen von XML-Dokumenten zu unterstützen. Das Paket enthält die beiden Klassen JDOMResult und JDOMSource. Die Klasse JDOMSource ist eine Wrapper-Klasse, die ein JDOM-Dokument als Parameter nimmt und diesen als Eingabe für das JAXP-TraX-Modell bereitstellt. Die Klasse JDOMResult enthält das Ergebnis der Transformation als JDOM-Dokument. Die beiden Klassen haben nur wenige Methoden, und in der API sind Beispiele für die Benutzung dieser Klassen angegeben. #### Das Paket org.jdom.xpath Im Paket org.jdom.xpath befindet sich nur eine Utility-Klasse XPath. Diese Klasse bildet die Basis für die Verwendung der Abfragesprache XPath mit JDOM. Eine kurze Einführung in XPath sowie Beispiele für den Einsatz in JDOM finden Sie in Abschnitt 7.7.12. Neben der Implementierung, die mit JDOM geliefert wird, kann auch eine spezielle Implementierung der XPath-Methoden für JDOM eingesetzt werden. JDOM bringt keine eigene XPath-Implementierung mit, sondern basiert auf der Open-Source-Implementierung Jaxen (http://jaxen.org/). #### Das Paket org.jdom.adapters Die Klassen des Pakets org.jdom.adapters erlauben es JDOM, existierende DOM-Implementierungen zu nutzen. Sie sind nur interessant für diejenigen, die selbst einen XML-Parser an JDOM anpassen wollen. ### 7.7.3 Die Document-Klasse Dokumente werden bei JDOM über die Klasse Document verwaltet. Ein Dokument besteht aus einem DocType, einer ProcessingInstruction, einem Wurzelelement und Kommentaren. Die Klasse Document gibt es auch in der Standardschnittstelle für das DOM. Falls sowohl JDOM als auch DOM verwendet werden, muss für die Klasse Document der voll qualifizierte Klassenname mit vollständiger Angabe der Pakete verwendet werden, weil sonst nicht klar ist, welche Document-Klasse verwendet wird. #### Ein JDOM-Document im Speicher erstellen Um ein Document-Objekt zu erzeugen, bietet die Klasse drei Konstruktoren an. Über einen Standard-Konstruktor erzeugen wir ein leeres Dokument. Dieses können wir später bearbeiten, indem wir zum Beispiel Elemente (Objekte vom Typ Element), Entitäten oder Kommentare einfügen. Ein neues Dokument mit einem Element erhalten wir über einen Konstruktor, zu dem wir ein Wurzelelement angeben. Jedes XML-Dokument hat ein Wurzelelement.
Beispiel
Die folgende Zeile erzeugt ein JDOM-Dokument mit einem Wurzelelement: Listing 7.27: com/tutego/insel/xml/jdom/CreateRoot.java, main()
    Document doc = new Document( new Element("party") );
In XML formatiert, könnte das so aussehen:
    <party>
    </party>
### 7.7.4 Eingaben aus der Datei lesen Ein zweiter Weg, um ein JDOM-Dokument anzulegen, führt über einen Eingabestrom oder eine Datei. Dafür benötigen wir einen Builder, zum Beispiel den SAXBuilder (den wir bevorzugen wollen).
Beispiel
Lies die Datei party.xml ein: Listing 7.28: com/tutego/insel/xml/jdom/ReadXmlFile.java, main()
    String filename = "party.xml";
    Document doc = new SAXBuilder().build( filename );
Die möglichen Ausnahmen IOException und JDOMException muss die Anwendung abfangen.
Die Klasse Document bietet selbst keine Lese-Methoden. Es sind immer die Builder, die Document-Objekte liefern. Es ist ebenso möglich, ein JDOM-Dokument mithilfe des DOM-Parsers über DOMBuilder zu erzeugen. Neben den Standard-Konstruktoren bei SAXBuilder und DOMBuilder lässt sich unter anderem ein boolean-Wert angeben, der die Validierung auf wohldefinierten XML-Code einschaltet.
Tipp
Wenn ein DOM-Baum nicht schon vorliegt, ist es sinnvoll, ein JDOM-Dokument stets mit dem SAX-Parser zu erzeugen. Das schont die Ressourcen und geht viel schneller, weil keine spezielle Datenstruktur für den DOM-Baum erzeugt werden muss. Das Ergebnis ist in beiden Fällen ein JDOM-Dokument, das die XML-Datei in einer baumähnlichen Struktur abbildet.
    class org.jdom.input.SAXBuilder
    implements Parent
SAXBuilder() Baut einen XML-Leser auf Basis von SAX auf. Es wird nicht validiert. SAXBuilder(boolean validate) Baut einen validierenden SAXBuilder auf. Document build(File file) Document build(InputSource in) Document build(InputStream in) Document build(InputStream in, String systemId) Document build(Reader characterStream) Document build(Reader characterStream, String systemId) Document build(String systemId) Document build(URL url) Baut ein JDOM-Dokument aus der gegebenen Quelle auf. Im Fall des String-Arguments handelt es sich um einen URI-Namen und nicht um ein XML-Dokument im String. ### 7.7.5 Das Dokument im XML-Format ausgeben Mit einem XMLOutputter lässt sich der interne JDOM-Baum als XML-Datenstrom in einen OutputStream oder Writer schieben.
Beispiel
Gib das JDOM-Dokument auf der Konsole aus: Listing 7.29: com/tutego/insel/xml/jdom/ReadXmlFile.java, main()
    XMLOutputter out = new XMLOutputter();
    out.output( doc, System.out );
Die Standard-Parametrisierung des Formatierers schreibt die XML-Daten mit schönen Einrückungen. Jeder Eintrag kommt in eine einzelne Zeile. Weitere Anpassungen der Formatierung übernimmt ein org.jdom.output.Format-Objekt. Einige statische Methoden bereiten Format-Objekte mit unterschiedlichen Belegungen vor, so getPrettyFormat() für hübsch eingerückte Ausgaben und getCompactFormat() mit sogenannter Leerraum-Normalisierung, wie es die API-Dokumentation nennt.
    XMLOutputter out = new XMLOutputter( Format.getPrettyFormat() );
    out.output( doc, System.out );
Unterschiedliche setXXX()-Methoden auf dem XMLOutputter-Objekt ermöglichen eine weitere individuelle Anpassung der Format-Objekte. Soll das Ergebnis als String vorliegen, kann outputString() verwendet werden, was ein String-Objekt liefert. ### 7.7.6 Der Dokumenttyp * Ein XML-Dokument beschreibt in seinem Dokumenttyp den Typ der Datei und besitzt oft einen Verweis auf die beschreibende DTD.
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, das wir nach den IDs fragen können. Über setDocType() kann der veränderte Dokumenttyp neu zugewiesen werden.
    class org.jdom.Document
    implements Parent
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üssen dann ein neues DocType-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 );
### 7.7.7 Elemente Jedes Dokument besteht aus einem Wurzelelement. Wir haben schon gesehen, dass dieses durch die allgemeine Klasse Element abgebildet wird. Mit dem Wurzelelement gelingt der Zugriff auf die anderen Elemente des Dokumentenbaums. #### Wurzelelement Die folgenden Beispieldateien verwenden die XML-Datei party.xml, um die Methoden von JDOM vorzustellen. Durch das Erzeugen eines leeren JDOM-Dokuments und die Methoden zur Erstellung von Elementen und Attributen kann JDOM den Dateiinhalt auch leicht aufbauen: Listing 7.30: 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 gelangen und von dort aus weitere Elemente oder Attribute auslesen zu können, erzeugen wir zunächst ein JDOM-Dokument aus der Datei party.xml und nutzen zum Zugriff getRootElement().
Beispiel
Lies die Datei party.xml, und erfrage das Wurzelelement: Listing 7.31: com/tutego/insel/xml/jdom/RootElement.java, main()
    Document doc = new SAXBuilder().build( "party.xml" );
    Element party = doc.getRootElement();
    class org.jdom.Document
    implements Parent
Element getRootElement() Gibt das Root-Element zurück oder null, falls kein Root-Element vorhanden ist. boolean isRootElement() Gibt einen Wahrheitswert zurück, 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 getRootElement() wird das Wurzelelement der XML-Datei zurückgegeben. Dieses Element ist der Ausgangspunkt für die weitere Verarbeitung der Datei. #### Zugriff auf Elemente Um ein bestimmtes Element zu erhalten, gibt es die Methode getChild(String name). Mit dieser Methode wird das nächste Unterelement des Elements zurückgegeben, das diesen Namen trägt.
Beispiel
Wenn wir den ersten Gast auf der Party haben möchten, schreiben wir: Listing 7.32: com/tutego/insel/xml/jdom/AlbertTheFirst.java, main()
    Element party = doc.getRootElement();
    Element albert = party.getChild( "gast" );
Wenn wir wissen wollen, was Albert trinkt, schreiben wir:
    Element albertGetraenk = albert.getChild( "getraenk" );
Durch eine Kaskadierung ist es möglich, über das Wurzelelement auf das Getränk des ersten Gastes zuzugreifen:
    Element albertGetraenk = party.getChild( "gast" ).getChild( "getraenk" );
Eine Liste mit allen Elementen liefert die Methode getChildren(). Sie gibt eine nicht generisch verwendete java.util.List mit allen Elementen dieses Namens zurück.[58](JDOM ist vor Java 5 entwickelt worden, und die Entwickler investieren keine Zeit mehr in die Weiterentwicklung. http://code.google.com/p/coffeedom/ ist eine Entwicklung von anderer Stelle, die Generics einführt. http://git.tuis.net/jdom/ ist ein alternativer Port. XOM nutzt nach außen keine Typen der Collection-API, denn spezielle XOM-Klassen wie Nodes und Elements sind Container und liefern typisierte Objekte. Leider implementieren sie keine neuen Java-Collection-API-Klassen wie Iterable. dom4j ist die einzige bekanntere XML-Bibliothek, die Generics einsetzt.)
Beispiel
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.
    class org.jdom.Element
    extends Content
    implements Parent
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 wider. 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. ### 7.7.8 Zugriff auf Elementinhalte 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. #### Elementinhalte auslesen und setzen 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, ist der Rückgabewert ein Leerstring.
Beispiel
Um an das erste Getränk von Albert zu kommen, schreiben wir: Listing 7.33: com/tutego/insel/xml/jdom/AlbertsDrink.java, main()
    Element party = doc.getRootElement();
    Element albertGetraenk = party.getChild( "gast" ).getChild( "getraenk" );
    String getraenk = albertGetraenk.getText();
    class org.jdom.Element
    extends Content
    implements Parent
String getText() Rückgabe des Inhalts des Elements. Dies beinhaltet alle Leerzeichen und CDATA-Sektionen. Falls der Elementinhalt nicht zurückgegeben werden kann, wird der leere String zurückgegeben. 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 der Inhalt eines untergeordneten Elements auch direkt ermittelt werden.
Beispiel
Lies den Text des ersten untergeordneten Elements mit dem Namen getraenk. Das übergeordnete Element von Getränk ist albert: Listing 7.34: com/tutego/insel/xml/jdom/AlbertsDrink.java, main()
    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
    extends Content
    implements Parent
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 Namensraum-Prä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 Namensraum-Präfixes. Falls kein Namensraum-Präfix existiert, wird ein Leerstring zurückgegeben. String getNamespaceURI() Rückgabe der Namensraum-URI, die dem Präfix dieses Elements zugeordnet ist, oder des Standardnamensraums. Falls keine URI gefunden werden kann, wird ein leerer String zurückgegeben. ### 7.7.9 Liste mit Unterelementen erzeugen * 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, und laufe sie mit einem Iterator ab: Listing 7.35: com/tutego/insel/xml/jdom/PartyList.java, main()
    List<?> partyInfo = party.getContent();
    Iterator<?> partyIterator = partyInfo.iterator();
    while ( partyIterator.hasNext() )
      System.out.println( partyIterator.next() );
    class org.jdom.Element
    extends Content
    implements Parent
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. ### 7.7.10 Neue Elemente einfügen und ändern 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
Erfrage eine Liste mit allen Unterelementen von albert, erzeuge ein neues Element, und füge es in die Liste ein: Listing 7.36: com/tutego/insel/xml/jdom/AlbertsWater.java, main()
    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 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. Dazu wird zuerst 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 wir 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 Methode removeChild entfernt das Element <getraenk>:
    Element party = doc.getRootElement();
    Element albert = party.getChild( "gast" );
Es werden nur die direkten Nachfolger durchsucht. Diese Methode findet das Element <getraenk>Wein</getraenk> nicht.
    party.removeChild( "getraenk" );
Mit removeChild() wird das Element <getraenk>Wein</getraenk> gelöscht.
    albert.removeChild( "getraenk" );
    class org.jdom.Element
    extends Content
    implements Parent
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. Von diesen Konstruktoren ist in den Beispielen nur der erste benutzt worden. boolean removeChild(String name) Entfernt das erste gefundene Unterelement mit dem Namen name, das 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(content child) Ergänzt den Inhalt des Elements um das Element als Unterelement. 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 oder null, falls das Element keinem Dokument zugeordnet ist. ### 7.7.11 Attributinhalte lesen und ändern 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". Diesen Wert liefert die Methode getAttribute(String).getValue() der Klasse Element.
Beispiel
Lies den Namen des ersten Gastes: Listing 7.37: com/tutego/insel/xml/jdom/Wedding, main()
    Element   party      = doc.getRootElement();
    Element   albert     = party.getChild( "gast" );
    Attribute albertAttr = albert.getAttribute( "name" );
    String albertName    = albert.getAttribute( "name" ).getValue();
Martina möchte wissen, ob Albert noch ledig ist:
    albert.getChild( "zustand" ).getAttribute( "ledig" ).getValue();
Auf ähnliche Weise lässt sich der Wert eines Attributs ändern. Dazu gibt es die Methoden setAttribute(String) der Klasse Attribute und addAttribute(Attribute) der Klasse Element.
Beispiel
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:
    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 );
    }
Das Beispiel macht 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
    extends Content
    implements Parent
Attribute getAttribute(String name) Rückgabe des Attributs mit dem Namen name, das keinem Namensraum zugeordnet ist. Falls das Element kein Attribut mit dem Namen name hat, ist die Rückgabe null. Attribute getAttribute(String name, Namespace ns) Verhält sich wie getAttribute(String) in dem Namensraum ns. List getAttributes() Rückgabe einer Liste aller Attribute eines Elements oder einer leeren Liste, falls das Element keine Attribute hat. String getAttributeValue(String name) Rückgabe des Attributwerts mit dem Namen name, dem kein Namensraum zugeordnet ist. Es wird null zurückgegeben, falls keine Attribute dieses Namens existieren, und der leere String, falls der Wert des Attributs leer ist. String getAttributeValue(String name, Namespace ns) Verhält sich wie getAttributeValue(String) in dem Namensraum ns. Element setAttributes(List attributes) Fügt alle Attribute der Liste dem Element hinzu. Alle vorhandenen Attribute werden entfernt. Das geänderte Element wird zurückgegeben. Element addAttribute(Attribute attribute) Einfügen des Attributs attribute. Bereits vorhandene Attribute mit gleichem Namen und gleichem Namensraum werden ersetzt. 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 die Methode addAttribute(Attribute attribute) verwendet werden.
    class org.jdom.Attribute
    implements Serializable, Cloneable
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 Namensraum-Prä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. Attribute setValue(String value) Setzt den Wert dieses Attributs. ### 7.7.12 XPath Der Standard XPath (http://www.w3.org/TR/xpath20/) bietet eine Syntax, um einzelne Knoten oder Knotenmengen aus einer XML-Struktur zu erhalten, so wie auch eine Notation im Dateisystem die Angabe einer Datei erlaubt. Der XPath-Standard wird vom W3C verwaltet und findet in vielen Bereichen Anwendung, etwa in XSLT. XPath betrachtet die XML-Datenstruktur als Baum. Am Anfang dieses Baumes steht die XPath-Wurzel, die sich wie üblich vor dem ersten Element des XML-Dokuments befindet. Innerhalb des Baums kann ein XPath-Ausdruck die einzelnen Elemente, deren Attribute und Werte, Verarbeitungsanweisungen und Kommentare selektieren. Die folgenden Beispiele stellen den Zugriff auf Elemente, Elementwerte, Attribute und Attributwerte vor. #### Knoten(-mengen) selektieren XPath bietet zwei Notationen zur Selektierung: Die einfachere Form ist die Dateisystem-Notation, die sich an den Regeln für das UNIX-Dateisystem orientiert. Daneben gibt es noch eine spezielle XPath-Notation, die etwas komplizierter ist. In Tabelle 7.16 werden einige Sprachkonstrukte der beiden Notationen exemplarisch einander gegenübergestellt.

Tabelle 7.16: Dateisystem-Notation und XPath-Notation im Vergleich

Beschreibung | XPath-Notation | Dateisystem-Notation
Zugriff auf den ersten Knoten namens party | /child::party | /party
Übergeordnete Knoten verwenden | /child::party/child::gast/ child::zustand/parent::node() | /party/gast/zustand/..
Der erste Gast unserer Party | /child::party/child::gast[1] | /party/gast[1]
Alle ledigen Gäste | /child::party/child::gast/ child::zustand/ attribute::ledig[(child::text() = "true")] | /party/gast/ zustand[@ledig="true"]
Es gibt ebenso die Möglichkeit, auf Geschwisterknoten und den aktuellen Knoten zuzugreifen. Zudem können Knoten in Abhängigkeit von der Position im XML-Dokument und bestimmten Werten von Elementen und Attributen abgefragt werden. Um die Beispiele einfach zu halten, wollen wir allerdings immer die Dateisystem-Notation verwenden. #### XPath-APIs So, wie es unterschiedliche APIs zur Repräsentation der XML-Bäume im Speicher gibt (W3C DOM, JDOM, ...), gibt es auch mehrere XPath-APIs. Zwei wichtige sind: DOM Level 3 XPath: Eine programmiersprachenunabhängige API ausschließlich für Bäume nach dem offiziellen W3C-DOM-Modell. Das Paket javax.xml.xpath setzt diese API in Java um. Jaxen: Eine Java-API, die unterschiedliche DOM-Modelle wie DOM, JDOM und dom4j zusammenbringt. #### XPath mit JDOM Um XPath-Anfragen mit JDOM durchzuführen, steht die Klasse org.jdom.xpath.XPath vom JDOM im Zentrum. Im Hintergrund arbeitet Jaxen, sodass die JDOM-Klasse nur eine Fassade für die Jaxen-API ist. JDOM bringt das nötige Java-Archiv für Jaxen mit. Damit die folgenden Beispiele laufen, muss aus dem Ordner lib des Archivs jdom-1.1.1.zip die Jar-Datei jaxen.jar in den Klassenpfad aufgenommen werden. Unter http://jaxen.codehaus.org/releases.html lässt sich die jeweils aktuelle Version beziehen. Die statische Methode XPath.selectNodes(Object context, String path) von JDOM bekommt als Argument ein XML-Dokument und einen XPath-Ausdruck als String und liefert als Ergebnis eine Liste mit den selektierten Werten. Die Liste kann Elemente, Attribute oder Strings enthalten. Der XPath-Ausdruck legt fest, was aus dem XML-Dokument gewünscht ist.
Beispiel
Erzeuge eine Liste mit den Namen aller Gäste, und gib sie aus: Listing 7.38: com/tutego/insel/xpath/XPathDemo.java, Ausschnitt
    List<?> nameList = XPath.selectNodes( doc, "/party/gast/@name" );
    for ( Object object : nameList )
    {
      Attribute attribute = (Attribute) object;
      System.out.println( attribute.getValue() );
    }
Über die statische Methode newInstance(String path) lässt sich auch ein XPath-Objekt erzeugen; dann ist der XPath-Ausdruck schon vorcompiliert, was eine bessere Performance ergibt, wenn der gleiche Ausdruck auf unterschiedlichen JDOM-Bäumen angewendet wird (es entspricht in etwa dem Verhalten mit der Klasse Pattern und compile()). Die Selektion übernimmt anschließend die Methode selectNodes(Object context), die als Argument nur das XML-Dokument bekommt. Die Rückgabe ist wie bei der statischen Methode eine Liste mit den Werten, die diesem XPath-Ausdruck entsprechen.
Beispiel
Erzeuge ein Exemplar von XPath für einen Ausdruck zur Selektion von Getränken, und gib eine Liste aller Getränke auf den Bildschirm aus: Listing 7.39: com/tutego/insel/xpath/XPathDemo.java, Ausschnitt
    XPath xpath = XPath.newInstance( "/party/gast/getraenk" );
    List<?> drinkList = xpath.selectNodes( doc );

    for ( Object object : drinkList )
    {
      Element aktuellesElement= (Element) object;
      System.out.println( aktuellesElement.getValue() );
    }
Das Ergebnis dieser beiden Aufrufe ist immer eine Knotenmenge. Es gibt aber auch Situationen, in denen nur das erste Element der Ergebnisliste verarbeitet werden soll oder nur ein Element als Ergebnis bei einem XPath-Ausdruck möglich ist, wie zum Beispiel bei der Abfrage von Elementen mit Positionsangabe. Für diesen Fall bietet die Klasse XPath zwei praktische Methoden: Object selectSingleNode(Object context, String path) als statische Methode Object selectSingleNode(String path) als Objektmethode für vorhandene XPath-Objekte
Beispiel
Gib den Namen des ersten Gastes aus: Listing 7.40: com/tutego/insel/xpath/XPathDemo.java, Ausschnitt
    Object firstGuest = XPath.selectSingleNode( doc,
                                                "/party/gast[1]/@name" );
    System.out.println( ((Attribute) firstGuest).getValue() );
Die Möglichkeiten von XPath können als Alternative zu den Zugriffen über die Datenstrukturen von Java betrachtet werden. Es ist häufig einfacher, mit einem XPath-Ausdruck als mit einzelnen Methodenaufrufen den Pfad zu den Inhalten zu kodieren. Eine Anwendung, die dem Benutzer einen Zugriff auf die XML-Daten bietet, sollte auf jeden Fall XPath anbieten, weil dies der Standard für den Zugriff ist. Speziell für Datenbanken, die sich auf die Speicherung von XML-Dokumenten spezialisiert haben, ist es üblich, XPath als Abfragesprache zu verwenden. Als neuer Standard in diesem Umfeld entwickelt sich XQuery, wo eine SQL-ähnliche Syntax angeboten wird. Ebenso wird XPath im Standard XSLT verwendet, um Knoten für die Umwandlung auszuwählen. Wir stellen diesen Standard im nächsten Abschnitt kurz vor.
    class org.jdom.xpath.XPath
    implements Serializable
static XPath newInstance(String path) throws JDOMException Liefert ein Exemplar vom XPath mit vorcompiliertem XPath-Ausdruck path. static List selectNodes(Object context, String path) throws JDOMException Wertet den XPath-Ausdruck auf dem JDOM-Knoten aus und liefert eine Liste von Knoten, die auf den XPath-Ausdruck passen. static Object selectSingleNode(Object context, String path) throws JDOMException Wertet den XPath-Ausdruck auf dem JDOM-Knoten aus und liefert den atomaren Wert oder bei einer Liste das erste Element. abstract List selectNodes(Object context) throws JDOMException Wertet den vorcompilierten XPath-Ausdruck – gespeichert beim aktuellen XPath-Objekt – auf dem Knoten context auf. Ein XPath-Objekt baut newInstance() auf. ### Ihr Kommentar Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück | <top> | vor >>
Zum Katalog
Java 7 – Mehr als eine Insel Jetzt bestellen
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Buchempfehlungen
| Java und XML
| Einstieg in Eclipse 3.7
| Android 3
| NetBeans Platform 7
| Java ist auch eine Insel
| Apps entwickeln für Android 4
| Java 7
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

Copyright © Galileo Press 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das 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.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de