Wykład 08

Transkrypt

Wykład 08
Plan
Przetwarzanie dokumentów XML
i zaawansowane techniki WWW
Wykład 07
T. Romańczukiewicz
Jagiellonian University
2009/2010
T. Romańczukiewicz
XML 07
Plan
Plan
1
JAXB
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Plan
1
JAXB
Przypomnienie
Wstep
˛
Przykład
Typy danych
Unmarshalling
Dodawanie Nowych elementów
Marshalling
Podsumowanie
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
XML, poprawnie sformuowanie
Sposoby opisu XML
DTD
XML Schema
XPATH
Sposoby prezentacji
CSS
XSLT
DOM
SAX
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
DOM
DOM i SAX
Parser DOM wczytuje cały dokument do pamieci
˛ i tworzy obiekt DOM
przechowujac
˛ dane w strukturze drzewa.
DOM pozwala na swobodne poruszanie sie˛ po drzewie dokumentu.
W przypadku przetwarzania dużych i skomplikowanych plików XML moga˛ zostać
zużyte spore zasoby pamieciowe.
˛
SAX nie wczytuje całego dokumentu lecz działa jak parser strumieniowy
sterowany zdarzeniami.
Zdarzenia sa˛ zgłaszane gdy zostanie napotkany np element, dane tekstowe czy
przestrzeń nazw.
Obsługe˛ zdarzeń należy zaimplementować.
SAX nie umożliwia uzyskania swobodnego dostepu
˛
do dokumentu XML
Przetwarzanie z użyciem SAX jest jednokierunkowe - wcześniej przetworzone
dane nie moga˛ być ponownie odczytane bez ponownego uruchomienia całej
procedury.
Wymagania pamieciowe
˛
SAX sa˛ znacznie mniejsze niż DOM.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
JAXB
JAXB - Java Architecutre for XML Binding
Kolejny standard definiujacy
˛ dostep
˛ do plików XML-owych z poziomu jezyka
˛
programowania.
Obecnie najbardziej promowany jest przez Suna, ale dostepne
˛
sa˛ również inne
implementacje.
JAXB nie posiada nie ma tu ogólnego interfejsu do parsowania plików.
Interfejs tworzony na podstawie DTD lub XML-Schemy.
Dostajemy kompilator schematów (lub dtd), który z tych schematów generuje
klasy - dla każdego elementu XML powstaje jedna klasa.
Inne podobne narz˛edzia: Castor, XMLBeans (Apache),
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
JAXB a SAX i DOM
Zalety w stosunku do DOM-a:
mniejsze wymagania pamieciowe,
˛
dzieki
˛ temu, że nie ma narzutu na generyczność
DOM-a, w pamieci
˛ jest tylko to co trzeba
bardziej intuicyjny dostep
˛ do dokumentu, dzieki
˛ temu nie trzeba znać struktury
dokumentu
DTD nie jest interpretowane, tylko zaszyte w kodzie - dzieki
˛ temu wieksza
˛
wydajność
Zalety w stosunku do SAX-a:
łatwiejszy dostep
˛ do pliku - cały plik jest w pamieci
˛
SAX jest read-only, a JAXB umożliwia modyfikacje˛ i zapisywanie do pliku.
Model danych w SAX trzeba było tworzyć samodzielnie.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Podstawowe operacje udostepniane
˛
przez JAXB
Generowanie klas. XML Schema jest używana przez kompilator JAXB binding
compiler xjc do wygenerowania klas w oparciu o XML Schema
Kompilowanie klas.
Unmarshalling - zamiana pliku XML na obiekty Javove
Modyfikacja dokumentu XML (na kopii z pamieci)
˛
Walidacja - sprawdzenie poprawności z DTD (także dokonywane na dokumencie
w pamieci)
˛
Marshalling - zamiana obiektów Javy na dokument XML
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
JAXB - Przykład
https://jaxb.dev.java.net/tutorial/section_1_3-Hello-World.html
Listing 1: hello.xsd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="2.0">
<xsd:element name="Greetings" type="GreetingListType"/>
<xsd:complexType name="GreetingListType">
<xsd:sequence>
<xsd:element name="Greeting" type="GreetingType" maxOccurs="unbounded"/
>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="GreetingType">
<xsd:sequence>
<xsd:element name="Text" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="language" type="xsd:language"/>
</xsd:complexType>
</xsd:schema>
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 2: Wywołanie kompilatora JAXB Schema
1
2
3
4
5
6
$ xjc -p hello hello.xsd
parsing a schema...
compiling a schema...
hello/GreetingListType.java
hello/GreetingType.java
hello/ObjectFactory.java
Zostały wygenerowane trzy klasy (wraz z dokładnym javadociem), GreetingType i
GreetingListType odpowiadajace
˛ zadeklarowanym typom w schemacie oraz
ObjectFactory:
Listing 3: GreetingType
1
2
3
4
5
6
7
8
public class GreetingType {
(...)
public String getText() { return text; }
public void setText(String value) { this.text = value; }
public String getLanguage() {
return language; }
public void setLanguage(String value) { this.language = value;
(...)
}
}
Klasa GreetingType posiada metody do odczytywania i modyfikowania zawartości
tekstowej elementu oraz atrybutu.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 4: GreetingListType
1
2
3
4
5
6
7
8
9
10
11
12
public class GreetingListType {
@XmlElement(name = "Greeting", required = true)
protected List<GreetingType> greeting;
public List<GreetingType> getGreeting() {
if (greeting == null) {
greeting = new ArrayList<GreetingType>();
}
return this.greeting;
}
}
Aby dodać element do listy:
getGreeting().add(newItem);
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 5: ObjectFactory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ObjectFactory {
private final static QName _Greetings_QNAME = new QName("", "Greetings");
public ObjectFactory() {}
/∗ C r e a t e an i n s t a n c e o f G r e e t i n g L i s t T y p e ∗/
public GreetingListType createGreetingListType()
{ return new GreetingListType(); }
public GreetingType createGreetingType()
{ return new GreetingType(); }
@XmlElementDecl(namespace = "", name = "Greetings")
public JAXBElement<GreetingListType> createGreetings(GreetingListType value)
{ return new JAXBElement<GreetingListType>(_Greetings_QNAME,
GreetingListType.class, null, value); }
}
Obiekt zawiera metody wytwórcze (ang. factory methods) dla każdego interfejsu
zawartości i elemetu
ObjectFactory
pozwala tworzyć nowe instancje reprezentacji dokumentu XML
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Przykładowe użycie
Listing 6: Hello
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Hello {
private ObjectFactory of;
private GreetingListType grList;
public Hello(){
of = new ObjectFactory();
grList = of.createGreetingListType();
}
public void make( String t, String l ){
GreetingType g = of.createGreetingType();
g.setText( t );
g.setLanguage( l );
grList.getGreeting().add( g );
}
public void marshal() {
try {
JAXBElement<GreetingListType> gl = of.createGreetings( grList );
JAXBContext jc = JAXBContext.newInstance( "hello" );
Marshaller m = jc.createMarshaller();
m.marshal( gl, System.out );
} catch( JAXBException jbe ){
// ...
}
}
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Konstruktor tworzy obiekt korzystajac
˛ z metody wytwórczej aby stworzyć element
główny XML typu GreetingListType.
Metoda make dodaje element do listy wraz z tekstem i atrybutem language.
wywołujac
˛ metode˛ marshal lista zamieniana jest na XML i wypisywana na
standardowe wyjście.
Listing 7: Użycie
1
2
3
4
5
6
Hello h
h.make(
h.make(
h.make(
= new Hello();
"Bonjour, madame", "fr" );
"Hey, you", "en" );
"Yo nopot, kivanok", "hu" );
h.marshal();
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Co prawda dane w XML sa˛ przechowywane zawsze jako tekst, ale dzieki
˛ schematom
można dokładniej określić typ tych danych. Dane te moga˛ być mapowane na typy Javy.
Przykład:
Listing 8: Typy
1
2
3
4
5
6
<xsd:simpleType name="GroupType">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive value="255"/>
</xsd:restriction>
</xsd:simpleType>
1
2
3
4
5
public class ElementType {
protected int group;
public int getGroup() { return group; }
public void setGroup(int value) {
this.group = value;
}
Listing 9: Wynik xjc
}
Typ <xsd:restriction base="xsd:int"> został zinterpretowany jako int, ale w całej klasie
nie ma obsługi ograniczeń podanych w schemacie.
Uwaga!
JAXB nie dostarcza mechanizmów chroniacych
˛
zakres, pattern i inne zaweżenia
˛
schematu. Wszystko to jest sprawdzane dopiero w momencie walidacji.
T. Romańczukiewicz
XML 07
JAXB
XML Schema Type
xsd:string
xsd:integer
xsd:int
xsd.long
xsd:short
xsd:decimal
xsd:float
xsd:double
xsd:boolean
xsd:byte
xsd:QName
xsd:dateTime
xsd:base64Binary
xsd:hexBinary
xsd:unsignedInt
xsd:unsignedShort
xsd:unsignedByte
xsd:time
xsd:date
xsd:anySimpleType
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Java Data Type
java.lang.String
java.math.BigInteger
int
long
short
java.math.BigDecimal
float
double
boolean
byte
javax.xml.namespace.QName
java.util.Calendar
byte[]
byte[]
long
int
short
java.util.Calendar
java.util.Calendar
java.lang.String
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 10: Listy
1
2
3
4
5
6
7
<xsd:simpleType name="NumberListType">
<xsd:list itemType="xsd:int"/>
</xsd:simpleType>
<xsd:simpleType name="StringListType">
<xsd:list itemType="xsd:string"/>
<!−− d a n g e r o u s ! −−>
</xsd:simpleType>
W pierwszym przypadku zostanie utworzona lista
protected List<Integer>numbers = new ArrayList<Integer>();
Analogiczie w drugim przypadku, ale w XML reprezentacja˛ bedzie
˛
lista wartości
oddzielonych białymi znakami. Jeśli wartości bed
˛ a˛ posiadały białe spacje to może być
problem. Zaleca sie˛ zatem stosowanie typów złożonych.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Również <xsd:all>, <xsd:union>, <xsd:choice> oraz <xsd:sequence> moga˛ być
powiazane
˛
z niektórymi strukturami danych Javy takimi jak array, list, structure (lub
record) i union.
Listing 11: sequence
1
2
3
4
5
6
<xsd:complexType name="PointType">
<xsd:sequence>
<xsd:element name="X" type="xsd:int"/>
<xsd:element name="Y" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
wynik kompilowania
Listing 12: sequence w javie
1
2
3
4
5
6
7
8
9
public class PointType {
protected int x;
protected int y;
public
public
public
public
int getX() { return x;
void setX(int value) {
int getY() { return y;
void setY(int value) {
}
this.x = value; }
}
this.y = value; }
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 13: xsd:union
1
2
3
4
5
6
7
8
9
10
11
12
13
<xsd:simpleType name="SpeedOrNumberType">
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:int">
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="+?d+"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
Jako typ prosty unia zostanie powiazana
˛
ze zmienna˛ typu String.
Listing 14: xsd:all
1
2
3
4
5
6
7
8
<xsd:complexType name="DinnerType">
<xsd:all>
<xsd:element name="Starter" type="xsd:string" minOccurs="0"/>
<xsd:element name="Soup"
type="xsd:string" minOccurs="0"/>
<xsd:element name="Entree" type="xsd:string"/>
<xsd:element name="Dessert" type="xsd:string" minOccurs="0"/>
</xsd:all>
</xsd:complexType>
Zostanie utworzona klasa zawierajaca
˛ zmienne starter, soup itd.
Uwaga! maxOccurs nie może mieć wartości wiekszej
˛
niż 1.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 15: xsd:enumeration
1
2
3
4
5
6
7
8
9
10
<xsd:simpleType name="IXLType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="eStwA"/>
<xsd:enumeration value="eStwS"/>
<xsd:enumeration value="SpDrL"/>
<xsd:enumeration value="SpDrS"/>
<xsd:enumeration value="VGS80"/>
</xsd:restriction>
</xsd:simpleType>
\begin{lstlisting}
Listing 16: xsd:enumeration w Javie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public enum IXLType {
E_STW_A("eStwA"),
E_STW_S("eStwS"),
SP_DR_L("SpDrL"),
SP_DR_S("SpDrS"),
VGS_80("VGS80");
private final String value;
IXLType(String v) {
value = v;
}
public String value() {
return value;
}
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Listing 17: xsd:enumeration
1
2
3
4
5
6
7
8
9
<xsd:simpleType name="IXLType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="eStwA"/>
<xsd:enumeration value="eStwS"/>
<xsd:enumeration value="SpDrL"/>
<xsd:enumeration value="SpDrS"/>
<xsd:enumeration value="VGS80"/>
</xsd:restriction>
</xsd:simpleType>
Listing 18: xsd:enumeration w Javie
1
2
3
4
5
6
7
8
9
10
11
12
public enum IXLType {
E_STW_A("eStwA"),
E_STW_S("eStwS"),
SP_DR_L("SpDrL"),
SP_DR_S("SpDrS"),
VGS_80("VGS80");
private final String value;
IXLType(String v) { value = v;}
public String value() { return value; }
}
Nazwy zostały zmienione.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Można też w taki sposób:
Listing 19: xsd:enumeration
1
2
3
4
5
6
7
8
9
<xsd:simpleType name="IXLType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="eStwA"/>
<xsd:annotation><xsd:appinfo>
<jxb:typesafeEnumMember name="eStwA"/>
</xsd:appinfo></xsd:annotation>
...
</xsd:restriction>
</xsd:simpleType>
Uwaga: w schemacie musi zostać dołaczona
˛
przestrzeń nazw
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
Listing 20: xsd:enumeration w Javie
1
2
3
4
5
6
7
8
9
10
11
public enum IXLType {
eStwA,
eStwS,
SpDrL,
SpDrS,
VGS80;
public String value() {
...
return name();
}
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Unmarshalling
Po powiazaniu
˛
klas Javy z typami XML Schema przy pomocy xjc można przystapić
˛ do
wczytywania danych.
Unmarshalling
czyli zamiana pliku XML na obiekty Javy
Najporościej utworzyć obiekt JAXBContext, nastepnie
˛
Unmarshaller i wywołać
metode˛ unmrshal.
Obiekt JAXBContext zawiera informacje wiaż
˛ ace
˛ informacje pomiedzy
˛
XML i Java.
˛
Można go utworzyć przy pomocy metody newInstance z parametrem bed
˛ acym
˛
nazwa˛ pakietu utworzonego przez xjc
Z tego kontekstu można utworzyć obiekt Unmarshaller, którego metoda unmarshal
zwraca obiekt JAXBElement powiazany
˛
z elementem głównym dokumentu.
Listing 21: xsd:enumeration w Javie
1
2
3
4
5
6
7
8
public <T> T unmarshal( Class<T> docClass, InputStream inputStream )
throws JAXBException {
String packageName = docClass.getPackage().getName();
JAXBContext jc = JAXBContext.newInstance( packageName );
Unmarshaller u = jc.createUnmarshaller();
JAXBElement<T> doc = (JAXBElement<T>)u.unmarshal( inputStream );
return doc.getValue();
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Walidacja
Przed przekształceniem danych z dokumentu XML na obiekty Javy można wykonać
walidacji.
Sam JAXB nie stosuje sie˛ do ograniczeń narzuconych przez schemat. Należy zatem te˛
operacje˛ przeprowadzić przed procedura˛ unmarshal i po marshal.
Służa˛ do tego obiekt klasy javax.xml.validation.Schema, który zostaje przekazany do
obiektu Unmarshaller.
Listing 22: Walidacja
1
2
3
4
5
6
7
8
9
10
11
12
13
Schema mySchema;
SchemaFactory sf =
SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
try {
mySchema = sf.newSchema( file );
} catch( SAXException saxe ){
/ / . . . ( error handling )
mySchema = null;
}
JAXBContext jc = JAXBContext.newInstance( packagePath );
Unmarshaller u = jc.createUnmarshaller();
u.setSchema( mySchema );
W przypadku gdy walidacja zawiedzie zostanie rzucony wyjatek.
˛
Wyjatki
˛ takie moge˛
być obsługiwane przez interfejs javax.xml.bind.ValidationEventHandler
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Kontekst JAXB
Obiekt JAXBContext tworzony jest na samym poczatku
˛
operacji wczytywania pliku
XML.
Można go utworzyć np.
JAXBContext ctxt = JAXBContext.newInstance( "some foo:more.bar");
gdzie
dwukropkiem oddziela sie˛ pakiety.
Każdy pakiet musi zawierać klase˛ ObjectFactory lub plik jaxb.index:
Listing 23: jaxb.index
1
2
3
4
5
# p a c k a g e some . f o o
# c l a s s some . f o o . Foo
Foo
# i n n e r c l a s s some . f o o . Foo . Boo
Foo.Boo
zawierajacy
˛ liste˛ klas w danym pakiecie.
Klasy ObjectFactory sa˛ generowane ze schematu
Innym sposobem utworzenia kontekstu jest podanie listy wszystkich klas:
JAXBContext ctxt = JAXBContext.newInstance( Foo.class, Bar.class );
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Użycie danych
Dane można odczytywać przy pomocy metod typu get a zapisywać przy pomocy
metod typu set. Wygodniej jest jednak stworzyć klasy obsługujace
˛ poszczególne typy
schematu. Ich metody moga˛ przetwarzać atrybuty i elementy potomne wywołujac
˛ ich
handlery.
Listing 24: XML Schema
<xsd:complexType name="PersonType">
<xsd:sequence>
<xsd:element name="Name" type="NameType">
<xsd:element name="Addr" type="AddrType" minOccurs="0">
<xsd:element name="Child" type="ChildType" minOccurs="0" maxOccurs="
unbounded">
6
</xsd:sequence>
7
<xsd:attribute name="resident" type="xsd:boolean"/>
8 </xsd:complexType>
1
2
3
4
5
9
10
11
12
13
14
<xsd:complexType name="ChildType">
<xsd:complexContent>
<xsd:extension base="PersonType"/>
</xsd:complexContent>
</xsd:complexType>
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Użycie danych c.d
Listing 25: Handler classes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
abstract class Handler {
protected static Map<Class<?>,Handler> ourClass2Conv = new HashMap<Class<?>,
Handler>();
static {
ourClass2Conv.put( PersonType.class, new PersonHandler() );
ourClass2Conv.put( NameType.class,
new NameHandler() );
ourClass2Conv.put( AddrType.class,
new AddrHandler() );
ourClass2Conv.put( ChildType.class, new ChildHandler() );
// ...
}
public abstract void handle( Object o );
protected void process( Object obj ){
if( obj != null ){
Handler h = ourClass2Conv.get( obj.getClass() );
if( h != null ){ h.handle( obj );
}
}
}
protected <T> void processList( List<T> list ){
for( T obj: list ){
Handler h = this.getHandler( obj );
h.process( obj );
}
}
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Użycie danych c.d
Listing 26: Handler classes
1
2
3
4
5
6
7
8
class PersonHandler extends Handler {
public void handle( Object o ){
PersonType p = (PersonType)o;
process( p.getName() );
if( p.isResident() ){ process( p.getAddr() );
processList( p.getChild );
}
}
T. Romańczukiewicz
XML 07
}
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
ObjectFactory
Jedna˛ z klas wygenerowanych przez xjc jest klasa ObjectFactory. Klasa ta zawiera
metody do tworzenia elementów reprezentowanych przez objekty JAXBElement<?>:
Listing 27: ObjectFactory
1
2
3
ObjectFactory objFact = new ObjectFactory();
RulebaseType rulebase = objFact.createRulebaseType();
JAXBElement<RulebaseType> doc = objFact.createRulebase( rulebase );
- znacznik elementu głównego.
proste elementy nie potrzebuja˛ JAXBElement<?>. Można je utworzyć bezpośrednio z
wywołania metody:
rulebase
ModuleType module = objFact.createModuleType();
Objekt JAXBElement<?> jest wymagany w przypadku elementów zawierajacych
˛
sekwencje˛ elementów tego samego typu ale o innych znacznikach:
Listing 28: Przykład
1
2
3
4
5
6
7
8
<xsd:complexType name="FooBarListType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="foo" type="FooBarType"/>
<xsd:element name="bar" type="FooBarType"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
ObjectFactory c.d.
Listing 29: ObjectFactory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FooBarListType fblElem = objFact.createFooBarListType();
List<JAXBElement<FooBarType>> fbList = fblElem.getFooOrBar();
/ / create a " foo " element
FooBarType foo = objFact.createFooBarType();
/ / . . . ( add a t t r i b u t e s and c o m p o n e n t s t o f o o )
/ / C r e a t e t h e e l e m e n t <f o o > . . . < / f o o >
JAXBElement<FooBarType> fooElem = objFact.createFooBarTypeFoo( foo );
/ / Add i t t o i t s p a r e n t ’ s l i s t .
fbList.add( fooElem );
/ / c r e a t e a " bar " e l e m e n t
FooBarType bar = objFact.createFooBarType();
/ / . . . ( add a t t r i b u t e s and c o m p o n e n t s t o b a r )
/ / C r e a t e t h e e l e m e n t <bar > . . . < / bar >
JAXBElement<FooBarType> barElem = objFact.createFooBarTypeBar( bar );
/ / Add i t t o i t s p a r e n t ’ s l i s t .
fbList.add( barElem );
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Aby dodać element potomny x wewnatrz
˛ elementu current (np. głównego) należy
Stworzyć element xElem przy pomocy metody createX.
Dodać nowo stworzony current.setX(
xElem ).
Powtórzyć ten proces rekurencyjnie dla elementów potomnych nowego elementu
Listing 30: Dodawanie nowych obiektów
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/ / C r e a t e o r d e r and i n s e r t i n t o p−l e v e l document , a l i s t o f o r d e r s
OrderType orderElem = objFact.createOrderType();
folder.getOrders().add( orderElem );
/ / C r e a t e and i n s e r t t h e c u s t o m e r e l e m e n t .
CustomerType custElem = objFact.createCustomerType();
orderElem.setCustomer( custElem );
/ / Complete customer .
custElem.setId( custId );
custElem.setName( custName );
/ / C r e a t e and add i t e m e l e m e n t s .
List<ItemType> itemList = orderElem.getItems();
for( Item item: items ){
ItemType itemElem = objFact.createItemType();
itemList.add( itemElem );
itemElem.setId( item.id );
itemElem.setQuantity( item.qtty );
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Dodawanie Nowych elementów c.d.
Listing 31: schemat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<xsd:complexType name="CustomerType">
<xsd:sequence>
<xsd:element name="id"
type="xsd:int"/>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ItemType">
<xsd:sequence>
<xsd:element name="id"
type="xsd:string"/>
<xsd:element name="quantity" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="OrderType">
<xsd:sequence>
<xsd:element name="customer" type="CustomerType"/>
<xsd:element name="items"
type="ItemType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="folder">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="orders"
</xsd:sequence>
</xsd:complexType>
</xsd:element>
type="OrderType" maxOccurs="unbounded"/>
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
Marshalling
Końcowym etapem tworzenia lub modyfikowania dokumentu XML jest procedura
zwana Marshalling.
Po utworzeniu obiektu Marshaller z obiektu JAXBContext można ustawić szereg
właściwości (np ustawianie formatowania wydruku, sposobu dołaczenia
˛
schematu,
strony kodowej itp.)
Listing 32: Marshalling
1
2
3
4
5
6
7
8
9
10
11
12
import java.io.*;
import javax.xml.bind.*
void writeDocument( Object document, String pathname )
throws JAXBException, IOException {
Class<T> clazz = document.getValue().getClass();
JAXBContext context =
JAXBContext.newInstance( clazz.getPackage().getName() );
Marshaller m = context.createMarshaller();
m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.marshal( document, new FileOutputStream( pathname ) );
}
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
JAXB
JAXB jest architektura˛ powiaza
˛ ń pomiedzy
˛
XML i klasami Javy
Najpierw na podstawie XML Schema generowane sa˛ klasy odpowiadajace
˛ typom
zadeklarowanym w schemacie.
Klasy te zawieraja˛ metody do czytania i manipulacji obiektami reprezentujacymi
˛
elementy XML
Typy Javy nie zachowuja˛ restrykcji nakładanych w schemacie.
Przed wczytaniem danych lub po ich zapisaniu do pliku możliwa jest walidacja.
Generowana jest też klasa ObjectFactory pozwalajaca
˛ tworzyć nowe instancje
reprezentacji dokumentu XML
Dokument XML wczytywany jest w trakcie procedury Unmarshalling na podstawie
kontekstu zawierajacego
˛
informacje o pakiecie.
Po modyfikacji zmiennych można zapisać dane do pliku przy pomocy metody
Marshalling.
T. Romańczukiewicz
XML 07
JAXB
Przypomnienie Wstep
˛
Przykład Typy danych Unmarshalling Dodaw
JAXB a DOM i SAX
DOM wczytywał cały dokument do pamieci
˛
Dane przechowywane były w uniwersalnej strukturze drzewa
Dzieki
˛ odpowiednim metodom można sie˛ było poruszać po całym drzewie
dokumentu
SAX przetwarzał dokument w trakcie czytania.
Aby stworzyć model danych należało samemu go zaimplementować.
SAX przetwarzał dokument jednokierunkowo.
JAXB sam tworzy strukture˛ danych na podstawie istniejacego
˛
już schematu.
Do danych jest dostep
˛ cały czas.
T. Romańczukiewicz
XML 07

Podobne dokumenty