100% found this document useful (1 vote)
1K views48 pages

JAXB

The document discusses the motivation and features of JAXB, an API for binding XML schemas to Java objects. JAXB allows XML data to be manipulated as Java objects for validation and type safety. It maps XML schemas to Java interfaces through a binding compiler. This mapping can then be used to unmarshal XML documents to objects, manipulate and validate the objects, and marshal them back to XML. The document outlines the default mapping and how it can be customized, and provides examples of using JAXB to unmarshal, read, update and marshal XML data.

Uploaded by

api-3750876
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
1K views48 pages

JAXB

The document discusses the motivation and features of JAXB, an API for binding XML schemas to Java objects. JAXB allows XML data to be manipulated as Java objects for validation and type safety. It maps XML schemas to Java interfaces through a binding compiler. This mapping can then be used to unmarshal XML documents to objects, manipulate and validate the objects, and marshal them back to XML. The document outlines the default mapping and how it can be customized, and provides examples of using JAXB to unmarshal, read, update and marshal XML data.

Uploaded by

api-3750876
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 48

The Java

Architecture For
)XML Binding )JAXB
:By
Yoav Zibin
Sharon Krisher
Motivation for JAXB
 The main purpose of XML Schema is:
 Validation of XML documents
 Any other purposes?
 Hint 1: determinism requirement
 Hint 2: the “default” attribute has nothing to do
with validation
<xs:attribute name="country" use=“optional”
default="Israel“ />
 Answer: Given a valid XML document, its
schema defines a unique data model
Motivation for JAXB
 Problem: How to manipulate this data model?
 DOM )data object model) solution:
 Pros: simple, general )a schema is not even required)
 Cons: no types, no compile-time checking
DOM pseudo-code example
root.getChild("Address").getChild("Number").getText()

 I wish to write … returns a string

root.getAddress().getNumber()

returns a number
JAXB solution:
Mapping XML Schema to Java interfaces

Binding Compiler

Source Java
schema interface
s

Pros: preserve types, compile-time checking


Cons: complex, specific to a certain schema
<xs:complexType name="AddressType">
<xs:sequence>
<xs:element name="Number" type="xs:unsignedInt"/>
<xs:element name="Street" type="xs:string"/>
</xs:sequence>
</xs:complexType>

Binding Compiler

public interface AddressType {


long getNumber();
void setNumber(long value);
Must be non-negative
String getStreet();
void setStreet(String value);
} Must be non-null
Talk Outline
 How is XML Schema mapped to Java
interfaces?
 What is the default mapping?
 How to customize this mapping?

 Second part of the lecture

 How do I use those Java interfaces?


 Next slides and a Demo!
Main Features
 Unmarshal: xml  objects
 Create / Read / Update / Delete objects
 Validate objects
 Marshal: objects  xml
 No roundtrip guarantees
 Marshal) Unmarshal)xml) ) ≠ xml
 We found that order is not always preserved

 But usually roundtrip holds


Step 1: Create XML Schema
Demo.xsd
<xs:element name="Person" type="PersonType"/>
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element name=“Name" type="xs:string"/>
<xs:element name="Address" type="AddressType"
minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddressType">
<xs:sequence>
<xs:element name="Number" type="xs:unsignedInt"/>
<xs:element name="Street" type="xs:string"/>
</xs:sequence>
</xs:complexType>
Step 2: Create XML Document
Demo.xml
<Person
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="C:\JAXB Demo\demo.xsd">
<Name>Sharon Krisher</Name>
<Address>
<Street>Iben Gevirol</Street>
<Number>57</Number>
</Address>
<Address>
<Street>Moshe Sharet</Street>
<Number>89</Number>
</Address>
</Person>

Check that your XML conforms to the Schema


Step 3: Run the binding compiler
 %JWSDP_HOME%\jaxb\bin\xjc -p demo demo.xsd
 A package named demo is created
)in the directory demo)
 The package contains )among other things):

 interface AddressType
 interface PersonType
AddressType and PersonType
public interface AddressType {
Must be non-negative
long getNumber();
void setNumber(long value);

String getStreet();
void setStreet(String value);
}
Must be non-null

public interface PersonType { Must be non-null


String getName();
void setName(String value);

/* List of AddressType */ Must contain at least one item


java.util.List getAddress();
}
In Java1.5: List<AddressType>
Step 4: Create Context
 The context is the entry point to the API
 Contains methods to create Marshaller,
Unmarshaller and Validator instances

JAXBContext context = JAXBContext.newInstance("demo");

The package name is demo


)Recall: xjc -p demo demo.xsd)
Step 5: Unmarshal: xml -> objects

Unmarshaller unmarshaller = Enable validation of


context.createUnmarshaller(); xml according to the
schema while
unmarshaller.setValidating(true); unmarshalling
PersonType person =
(PersonType) unmarshaller.unmarshal(
new FileInputStream("demo.xml") );
Step 6: Read

System.out.println("Person name=" +
person.getName() );

AddressType address = (AddressType)


person.getAddress().get(0);

System.out.println("First Address: " +


" Street=" + address.getStreet() +
" Number=" + address.getNumber() );
Step 7: Manipulate objects
// Update
person.setName("Yoav Zibin");

// Delete
List addressList = person.getAddress();
addressList.clear();
What happens if we validate there?
// Create
ObjectFactory objectFactory = new ObjectFactory();
AddressType newAddr = objectFactory.createAddressType();
newAddr.setStreet("Hanoter");
part of the demo package
newAddr.setNumber(5);
addressList.add( newAddr );
uses the factory pattern
Step 8: Validate on-demand
Validator validator = context.createValidator();

validator.validate(newAddr);

Check that we have set Street and Number,


and that Number is non-negative

validator.validate(person);

Check that we have set Name, and that


Address contains at least one item
Step 9: Marshal: objects -> xml
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
marshaller.marshal(person,
new FileOutputStream("output.xml"));

output.xml
<Person>
<Name>Yoav Zibin</Name>
<Address>
<Street>Hanoter</Street>
<Number>5</Number>
</Address>
</Person>
!And now, the Demo
First Part Summary
Similar Technologies
 Liquid XML Data Binding
 Similar to JAXB
 Supports all Schema constructs

 In addition to Java: C#, C++, Visual Basic 6

 Relaxer
 Instead of Schema uses Relax
 Castor.org
Second Part Outline
 Validation
 Mapping XML Schema to Java
 Naming
 Java Properties

 Simple and Complex Types

 Customization of the default mapping


Validation Constraints
 Three categories of constraints
 Type constraints: Legal values in simple types
 E.g., in every address, number is a non-negative
integer
 Local structural constraints
 E.g., in every person, address contains at least
one item
 Global structural constraints
 E.g., ID and IDREF
Validation
 Three forms of validation
 Unmarshal time validation )at unmarshal time)
 On-demand validation )at any chosen point in time)
 validateRoot)object) vs. validate)object)
 validateRoot includes global constraint checking
 Fail-fast validation )at all times)
 Currently not implemented
 Checks that the value provided to a set method is legal
 When validation errors occur an event is raised
)no exception) and validation continues, so that
several validation errors can be handled.
 Default handler raises an exception on first error
Unsupported Schema Concepts
 Substitution groups
 Type substitutions )xsi:type, block)
 Key, keyref, and unique
 anyAttribute

 No support for XPath or any other query


langauge 
Element vs. Type
 An element also has a qualified name
<xs:element name=“ugly_man" type="PersonType"/>
<xs:element name=“pretty_woman" type="PersonType"/>
<xs:complexType name="PersonType"> … </xs:complexType>

an empty interface which marks


the existence of a static QName

interface UglyMan extends PersonType, Element {}


interface PrettyWoman extends PersonType, Element {}
interface PersonType { … }

 When is the difference important? )next)


?When must I use elements
 Marshal: marshaller.marshal(Object, OutputStream)

E.g., when we marshal a PersonType:


<Name>Sharon Krisher</Name>
must be an element,
<Address>
<Street>Iben Gevirol</Street>
otherwise the resulting
<Number>57</Number> output is not a legal XML
</Address>

 General content
<xs:any/> Object getAny();
void setAny(Object elementOrValue);
Naming
 Problem: sometimes XML names
 are not legal java names
 do not comply to java naming standards

 The binding compiler creates proper


names
XML Name Class Name Method Name
mixedCaseName MixedCaseName getMixedCaseName
name-with-dash NameWithDash getNameWithDash
aa_bb-cc AaBbCc getAaBbCc
Java Properties
 Local schema components are mapped to:
 Simple property )get, set)
String getName();
void setName(String value);

 With customization: isSetName , unsetName


 List property
In Java1.5:
java.util.List getAddress(); List<AddressType>

 Indexed property )next)


Indexed Property
 Used instead of a list property when a
proper customization is applied

AddressType[] getAddress();
void setAddress(AddressType[] value);

AddressType getAddress(int index);


void setAddress(int index, AddressType value);
General Content Property
 The most general content property
 Can represent any content, however complex
 A list that can contain element interfaces and values
 Used for “problematic cases” :
 Name collisions due to derivation
 Mixed content
 Another example:
<xs:any maxOccurs="unbounded"/>
Each item can be
some element or
List getAny();
value
)Simple Types )partial diagram
SimpleType

Primtive List Union Restriction

List Next (1)


Represented as
validation
ID/IDREF String/Object constraints

date Calendar
maxInclusive

integer BigInteger
Enumeration
int int Next (2)
Simple Type:Union
<xs:complexType name="Date">
<xs:sequence>
<xs:element name="Month">
<xs:simpleType>
<xs:union memberTypes="xs:int xs:string"/>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>

Common supertype
Public interface Date { of )Integer, String)
Object getMonth(); is Object
void setMonth(Object);
}
Type SafeEnumeration
<xs:simpleType name="USState">
<xs:restriction base="xs:NCName">
<xs:enumeration value="AK"/>
<xs:enumeration value="NY"/>
</xs:restriction>
</xs:simpleType>

public class USState {


protected USSate(String v) {…}
public static final USState AK = …;
public static final USState NY = …;
public String getValue();
public static USState fromValue(String v) {…}
}
XML Schema Type System
Any

SimpleType finished ComplexType Represented as


a Java interface

SimpleContent ComplexContent *Sequence * Choice * All

*Extension Extension
Elements
Attributes
Restriction
abstract
*
The interface
use
default
nillable
minOccurs *
fixed maxOccurs
extends the base
type’s interface Represented as
( ) Next
* Java properties
Complex Types
 Represented as a Java interface
 Anonymous type
 An interface is created.
 The name is derived from the name of the

schema element + “Type”, e.g Foo  FooType


 Abstract types: no create method in
ObjectFactory
Complex Type: Simple Content
<xs:complexType name=“InternationalPrice">
<xs:simpleContent>
<xs:extension base="xs:int">
<xs:attribute name="currency“ type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

interface InternationalPrice {
int getValue();
void setValue(int);

String getCurrency();
void setCurrency(String);
}
Complex Type:Aggregation
<xs:element name="A" type="xs:int"/>

<xs:complexType name="Foo"> <xs:complexType name="Foo">


<xs:sequence> <xs:sequence>
<xs:element ref="A"/> <xs:element ref="A"/>
<xs:sequence>
<xs:element ref="B"/> <xs:element ref="B"/>
<xs:element ref="C"/> <xs:element ref="C"/>
</xs:sequence>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>

interface Foo {
int getA(); void setA(int);
int getB(); void setB(int);
int getC(); void setC(int);
}
Complex Type: Mixed Content
<xs:complexType name=“LetterBody"
mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>

</xs:sequence> XML fragment
</xs:complexType> Dear Mr.<name>Robert Smith</name>, …

interface lb
LetterBody LetterBody {
= ObjectFactory.createLetterBody();
interface
List gcl Name extends Element {
= lb.getContent();
String
gcl.add("Dear getValue();
Mr.");
void setValue(String);
gcl.add(ObjectFactory.createLetterBodyName("Robert Smith"));
}
… The list may contain
List getContent(); elements and strings
}
Complex Type:Choice
<xs:complexType name="FooBarType">
The programmer
<xs:choice>
is responsible to
<xs:element name="Foo" type="xs:int"/>
only set one of
<xs:element name="Bar"
Foo or Bar
type="xs:string"/>
</xs:choice>
Default
</xs:complexType>
Customization (Not implemented yet) public interface FooBarType {
int getFoo();
public interface FooBarType {
void setFoo(int value);
Object getFooOrBar();
String getBar();
void setFooOrBar(Object);
void setBar(String value);
}
boolean isSetFoo();
Common supertype of void unsetFoo();
)Integer, String) is boolean isSetBar();
Object void unsetBar();
Similar to union }
WhenmaxOccurs>1
<xs:complexType name="FooBarType">
<xs:choice maxOccurs="unbounded">
<xs:element name="Foo" type="xs:int"/>
<xs:element name="Bar" type="xs:string"/>
</xs:choice>
</xs:complexType>

public interface FooBarType {


interface Foo extends Element {…}
interface Bar extends Element {…}
// Items are instances of Foo and Bar
List getFooOrBar();
}

For a sequence: List getFooAndBar()


The programmer needs to make sure that
the list contains sequences of <A,B>.
Complex Type:All
 Mapped like Sequence
 Can’t have maxOccurs > 1
 No way to specify the order of elements
 Round trip doesn’t hold )order is not preserved):
unmarshal
XML
Objects
≠ in
memory
XML
marshal
Nillable elements
<xs:element name=“age" type=“xs:int" nillable="true"/>

Integer getAge();
void setAge(Integer value);

Java: setAge( new Integer(25) ) or setAge(null)

XML: <age>25</age> or <age xsi:nil="true"/>


Customization
 Used to augment the default mapping
 Customizations declared via special xml
tags
 May appear inside the source schema or
in a separate file
Uses of Customization
 Change default names of interfaces and
properties
 For a specific schema construct
 For an entire namespace

 Add a suffix or a prefix


 Change the types of properties
 Add javadoc declarations
Software Engineering Issues
 Weak Typing
Our suggestions:
 Marshal / Unmarshal : Object  Element
 IDREF: Object  Identifiable

 Sometimes JAXB doesn’t allow us to


control the order of elements
 Example 1: xs:all
 Example 2: next slide
Element Order Example
<xs:complexType name=“ABType">
<xs:choice>
<xs:sequence>
<xs:element name="A" type="xs:int"/>
<xs:element name="B" type="xs:string"/>
</xs:sequence>
<xs:sequence>
<xs:element name="B" type="xs:string"/>
<xs:element name="A" type="xs:int"/>
</xs:sequence> obj.setA(5);
</xs:choice> obj.setB(“a”);
</xs:complexType>
What happens
when we marshal
public interface ABType { obj?
int getA(); void setA(int value);
String getB(); void setB(String value); No roundtrip
}
It’s the programmer’s fault
 Taken from JAXB specification:
 “The caller must be sure …”
 “There is an expectation …”

 “User is responsible …”

 “… unexpected behavior may occur.”

Question: What is the output ?


xs:choice between Foo and Bar
obj.setAge(42);
obj.setFoo(42);
42 true
obj.unsetAge();
obj.setBar("A");
System.out.println(
System.out.println( obj.getAge() );
obj.isSetFoo() );
The END

 Any questions?

You might also like