Java Architecture for XML Binding (JAXB) ermöglicht den einfachen Umgang mit XML Dateien und Java. Man kann damit Java-Klassen erstellen, die auf Schema-Definitionen (z.B. XSD) von XML Dateien beruhen und diese dann einlesen und weiterverarbeiten. Die umgekehrte Richtung, also das Generieren von XML Dateien aus Java-Klassen ist damit ebenfalls möglich. Beides wird in diesem Artikel behandelt.
Voraussetzungen:
Java 1.6
Eclipse IDE for Java EE Developers, ich verwende hier das Indigo Release
Download einer aktuellen JAXB Version, z.B. 2.2.41.
Download JAXB-Eclipse-Plugin, z.B. JAXB-Builder
Installation/Konfiguration:
Java und die Eclipse IDE kann man einfach herunterladen und installieren. JAXB kann man an einem zentralen Ort speichern, um später die Libraries und evtl. Tools verwenden zu können (z.B. in den Classpath des Eclipse-Projektes einzubinden) – ich verwende hierfür meist das Verzeichnis „C:Program Files (x86)Java“
Das JAXB Eclipse Plugin muss man entpacken und im Plugin-Verzeichnis der Eclipse-Installation kopieren. Danach Eclipse neu starten. Falls der Wizard über „File > New > Project > JAXB“ nicht sichtbar ist, sollte man Eclipse beenden und mit dem Parameter „-clean“ neu starten, um den Plugin-Cache zu leeren.
Erst mal ohne Plugin…:
Um einen ersten Einblick in JAXB zu gewinnen, will ich veranschaulichen, wie man Klassen erstellt, ohne das Eclipse-Plugin zu nutzen. Der erste Schritt besteht darin, sich im Klaren zu sein, welche Daten man verarbeiten will und wie man diese in einer XML-Datei darstellen würde.
Im folgenden Beispiel will ich eine Anwendung erstellen, die in der Lage ist XML-Dateien zu verarbeiten, die Kontakte beinhaltet. Der Aufbau dieser XML-Datei könnte wie folgt aussehen:
<Kontakte>
<Kontakt>
<Name>Name1</Name>
<Vorname>Vorname1</Vorname>
<eMail>eMail1</eMail>
</Kontakt>
<Kontakt>
<Name>Name2</Name>
<Vorname>Vorname2</Vorname>
<eMail>eMail2</eMail>
</Kontakt>
<Kontakt>
<Name>Name3</Name>
<Vorname>Vorname3</Vorname>
<eMail>eMail3</eMail>
</Kontakt>
</Kontakte>
Es gibt eine Vielzahl von Online-Tools, die eine Umwandlung der XML-Datei in eine XSD-Datei (XML-Schema) ermöglichen, z.B. http://www.xmlforasp.net. Das Ergebnis sieht dann wie folgt aus:
<?xml version="1.0" encoding="utf-16"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Kontakte">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="Kontakt">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Name" type="xsd:string" />
<xsd:element name="Vorname" type="xsd:string" />
<xsd:element name="eMail" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Jetzt ist es an der Zeit mit Eclipse ein Java Projekt zu erstellen. Die XSD- und die XML-Datei können der Vollständigkeit halber in das Projektverzeichnis kopiert oder dort angelegt werden.

Mit dem Download der JAXB Version werden zwei Skriptdateien mit ausgeliefert, die im „bin“ Unterverzeichnis zu finden sind:
- „xjc“, um eine XML-Schemadatei in vollständig annotierte Java-Klassen zu kompilieren
- „schemagen“, um eine XML-Schemadatei aus Java-Klassen zu generieren
Mit dem „xjc“ Tool ist es also möglich, aus der Schema-Datei „Kontakte.xsd“ die entsprechenden JAXB-Java-Klassen zu generieren:

Die generierten Klassen werden im Unterverzeichnis „generated“ gespeichert. Ich kopieren das Verzeichnis in den src Unterordner des Eclipse Projektes und aktualisiere das Projektverzeichnis:

Es werden folgende Klassen und Methoden generiert:

Um die JAXB-Klassen nutzen zu können, müssen die im „lib“-Unterverzeichnis vorhandenen jar Dateien in den Build-Path des Projektes eingebunden werden:

Eine Anwendung, die die XML-Datei parst und weiterverarbeitet könnte etwa so aussehen:
package org.jkhofmann.dyndns;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import generated.*;
public class ParseKontakte {
/**
* @param args
*/
public static void main(String[] args) {
try {
// create JAXB context and instantiate marshaller
JAXBContext context = JAXBContext.newInstance(Kontakte.class);
Marshaller m = context.createMarshaller();
// get variables from our xml file, created before
System.out.println();
System.out.println("Kontakte XML File: ");
Unmarshaller um = context.createUnmarshaller();
Kontakte kontakte = (Kontakte) um.unmarshal(new FileReader(
"Kontakte.xml"));
for (int i = 0; i < kontakte.getKontakt().toArray().length; i++) {
System.out.println("Kontakt " + (i + 1) + ": "
+ "Name: " + kontakte.getKontakt().get(i).getName() + ", "
+ "Vorame: " + kontakte.getKontakt().get(i).getVorname() + ", "
+ "eMail: " + kontakte.getKontakt().get(i).getEMail() + ", "
);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Die entsprechende Ausgabe:
Kontakte XML File:
Kontakt 1: Name: Name1, Vorame: Vorname1, eMail: eMail1,
Kontakt 2: Name: Name2, Vorame: Vorname2, eMail: eMail2,
Kontakt 3: Name: Name3, Vorame: Vorname3, eMail: eMail3,
In einem weiteren Schritt will ich den Inhalt bearbeiten und erweitern:
package org.jkhofmann.dyndns;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import generated.*;
public class ParseKontakte {
/**
* @param args
*/
public static void main(String[] args) {
try {
// create JAXB context and instantiate marshaller
JAXBContext context = JAXBContext.newInstance(Kontakte.class);
Marshaller m = context.createMarshaller();
// get variables from our xml file, created before
System.out.println();
System.out.println("Kontakte XML File: ");
Unmarshaller um = context.createUnmarshaller();
Kontakte kontakte = (Kontakte) um.unmarshal(new FileReader(
"Kontakte.xml"));
for (int i = 0; i < kontakte.getKontakt().toArray().length; i++) {
System.out.println("Kontakt " + (i + 1) + ": "
+ "Name: " + kontakte.getKontakt().get(i).getName() + ", "
+ "Vorame: " + kontakte.getKontakt().get(i).getVorname() + ", "
+ "eMail: " + kontakte.getKontakt().get(i).getEMail() + ", "
);
}
// Add a new contact:
Kontakte.Kontakt k = new Kontakte.Kontakt();
k.setName("Name4");
k.setVorname("Vorname4");
k.setEMail("eMail4");
kontakte.getKontakt().add(k);
// write the enhanced contact list in a new XML file:
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(kontakte, System.out);
Writer w = null;
try {
w = new FileWriter("Kontakte2.xml");
m.marshal(kontakte, w);
} finally {
try {
w.close();
} catch (Exception e) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Die Ausgabe („Kontakte2.xml“):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Kontakte>
<Kontakt>
<Name>Name1</Name>
<Vorname>Vorname1</Vorname>
<eMail>eMail1</eMail>
</Kontakt>
<Kontakt>
<Name>Name2</Name>
<Vorname>Vorname2</Vorname>
<eMail>eMail2</eMail>
</Kontakt>
<Kontakt>
<Name>Name3</Name>
<Vorname>Vorname3</Vorname>
<eMail>eMail3</eMail>
</Kontakt>
<Kontakt>
<Name>Name4</Name>
<Vorname>Vorname4</Vorname>
<eMail>EMail4</eMail>
</Kontakt>
</Kontakte>
Ich finde, die Anwendung von JAXB ist im Vergleich zur Anwendung von SAX- oder DOM-Parsern (z.B. Xerces oder allgemeiner Java API for XML Processing – JAXP), wesentlich einfacher und zeitsparender. Anwender der Eclipse IDE können sich zusätzlich das Plugin „JAXB-Builder“ installieren. Die Anwendung wird im folgenden erläutert.
Jetzt mit dem Plugin…
Dazu erstellt man sich ein neues Projekt über „File > New > Project > JAXB“ und kopiert die XSD-Datei hinein:

Damit das Plugin funktioniert, muss man (wie gehabt) den Build-Path des Projektes um die JAXB-Libraries erweitern:

Durch einen Rechtsklick auf die XSD-Datei > Generate > JAXB Classes… kann man sich die JAXB-Klassen generieren lassen. Das Ergebnis ist das Gleiche wie oben, d.h. das Ausprogrammieren ist noch notwendig.

Man erspart sich allerdings den Umweg über die Kommandozeile, zum Generieren der JAXB-Java-Klassen.
Gefällt mir Wird geladen …