JAXB: Java Architecture for XML Binding

Werbung
JAXB
Java Architecture for XML Binding
http://jaxb.java.net
Warum JAXB?
JAXB ist eine schnelle und einfache Methode, um ein XML Schema
mit einer Java Repräsentation zu verbinden.
Damit ist es sehr einfach, XML Daten nach Java einzulesen, dort
zu verarbeiten und wieder nach XML abzuspeichern.
JAXB kann als Ersatz für DOM oder SAX benutzt werden.
Die Programmierdetails für das Lesen und Schreiben der XML
Daten bleiben verborgen. Wir müssen keine neuen Befehle
kennen lernen. Der Zugriff auf die Daten erfolgt nach den
Relationen, wie sie im XML Schema definiert sind.
Die Architektur von JAXB 2.0
Binding
Erzeugen der Java Klassen
xjc.exe -p pge schema.xsd –d out
Kompilieren der Java Klassen
javac out/pge/*.java
Unmarshalling der XML Dokumente, Benutzen der generierten
Objekte, Marshalling der Java Daten, Validierung, …
Übersetzung verschiedener Basis-Datentypen
XML-Datentyp
xsd:string
xsd:integer
xsd:int
xsd:long
xsd:short
xsd:decimal
xsd:float
xsd:double
xsd:boolean
xsd:byte
xsd:dateTime
xsd:time
xsd:date
xsd:anySimpleType
Java-Datentyp
java.lang.String
java.math.BigInteger
int
long
short
java.math.BigDecimal
float
double
boolean
byte
XMLGregorianCalendar
XMLGregorianCalendar
XMLGregorianCalendar
java.lang.String
Das Beispiel Schema
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="people">
<xs:complexType>
<xs:sequence>
<xs:element name="person" type="personType"
maxOccurs="unbounded"/>
<xs:element name="address" type="addressType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
...
Die erzeugten Java Klassen: People
People
List<PersonType> person;
List<AddressType> address;
List <PersonType> getPerson()
List <AddressType> getAddress()
Die erzeugten Klassen-Attribute mit
Zugriffsfunktionen
Die erzeugten Java Klassen: PersonType
PersonType
NameType name
BornType born
…
NameType getName()
void setName(NameType)
BornType getBorn()
void setBorn(BornType)
String getProfession()
...
<xs:complexType name="personType">
<xs:sequence>
<xs:element name="name" type="nameType"/>
<xs:element name="born" type="bornType"/>
<xs:element name="died" type="diedType"/>
…
</xs:sequence>
</xs:complexType>
Marshalling / Unmarshalling
Java
XML / XML
Java
Der Unmarshaller
Das JAXBContext-Objekt erstellt einen Zugriff zum JAXB
API. Damit wird ein Unmashaller erzeugt.
try{
JAXBContext jc = JAXBContext.newInstance( ClassName );
Unmarshaller u = jc.createUnmarshaller();
Object obj = u.unmarshal( InputStream | File | DocNode | ... )
...
} catch(JAXBException e) { . . . }
Validierung
Vor dem Lesen der XML Daten kann mit dem
Unmarshaller ein Schema verknüpft werden.
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema =
schemaFactory.newSchema(new File("People.xsd"));
unmarshaller.setSchema(schema);
Lesen der XML Daten
Der Unmarshaller liefert dann ein Objekt des Typs
PeopleType (gemäss dem Root-Element der XML
Struktur).
Object obj = u.unmarshal( ... ));
PeopleType people = (PeopleType) obj;
Navigation durch die Daten
Die generierten get-Methoden liefern die weiteren
Elemente
for(PersonType b : people.getPerson()) {
String firstName =
b.getName().getFirstName();
String lastName =
b.getName().getLastName();
}
Der Marshaller
Zum Schreiben der Daten nach XML erzeugen wir ein
JAXBContext und damit ein Marshaller Objekt.
JAXBContext jc = JAXBContext.newInstance(ClassName);
Marshaller ms = jc.createMarshaller();
ms.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
// Formatiertes Schreiben der Daten
ms.marshal( people,
new FileOutputStream( FileName ));
Validierung
Auch der Marshaller kann durch Setzen eines Schemas
validierend gemacht werden.
SchemaFactory sf = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema( SchemaFile );
marshaller.setSchema(schema);
Customizing
Anpassen der Java Klassen Namen
Definieren der generierten Klassen
Im Schema können die gewünschten (Ziel-) Klassen
Namen definiert werden:
<xs:complexType name="addressType">
<xs:annotation>
<xs:appinfo>
<jxb:class name="Address"/>
</xs:appinfo>
</xs:annotation>
...
</complexType>
Definieren der Membervariablen
Ebenso die gewünschten (Ziel-) Membervariablen
<xs:attribute name="id" type="xs:string">
<xs:annotation>
<xs:appinfo>
<jxb:property name="addressId"/>
</xs:appinfo>
</xs:annotation>
...
</xs:attribute>
Externes Binding
Konfigurations-File
Die hobby-Elemente der Personen sollen in einer
Member-Variablen „hobbyList“ abgelegt werden:
<jxb:bindings
node="//xs:complexType[@name='personType']">
<jxb:bindings node=".//xs:element[@name='hobby']">
<jxb:property name="hobbyList"/>
</jxb:bindings>
</jxb:bindings>
Bindings File
Die name-Elemente der Personen sollen in einer Klasse
„Name“ abgelegt werden
<jxb:bindings node="//xs:complexType[@name='nameType']">
<jxb:class name="Name"/>
</jxb:bindings>
Erzeugen eines XML Schemas
Schemagen.exe
Aus den Java Klassen lässt sich mit Hilfe von
Annotations (@XmlType, @XmlElement, … ) das
dazu passende Schema generieren.
Der Aufruf zum Erzeugen des Schemas lautet
schemagen.exe package\*.java
Ein Beispiel: Die Klasse People
// serialize all member variables
@XmlAccessorType(XmlAccessType.FIELD)
// in the following order
@XmlType( propOrder = { "person", "address" })
// people is the root element
@XmlRootElement(name = "people")
public class People {
@XmlElement(required=true)
protected List<PersonType> person;
@XmlElement(required=true)
protected List<AddressType> address;
public List<PersonType> getPerson() { . . . }
public List<AddressType> getAddress() { . . . }
}
Das erzeugte Schema
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="people">
<xs:complexType>
<xs:sequence>
<xs:element name="person"
type="personType" maxOccurs="unbounded"/>
<xs:element name="address"
type="addressType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
. . .
Die Klasse Address
@XmlType( name = "addressType",
propOrder = { "country",
"city“ })
public class Address {
@XmlAttribute(required=true)
private String id
@XmlElement(name="country", required=true)
private String country
@XmlElement(required=true)
private String city;
public String getId() { . . . }
public void setId(String value) { . . . }
public String getCountry() { . . . }
public void setCountry(String value) { . . . }
. . .
}
Das erzeugte Schema
<xs:complexType name="peopleType">
<xs:sequence>
<xs:element name="person" type="personType"
maxOccurs="unbounded"/>
<xs:element name="address" type="addressType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addressType">
<xs:sequence>
<xs:element name="country" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"
use="required"/>
</xs:complexType>
. . .
Marshalling ohne Object Factory
Herunterladen