JAXB Java Architecture for XML Binding What is

JAXB Java Architecture for XML Binding

What is JAXB? n n JAXB is Java Architecture for XML Binding SAX and DOM are generic XML parsers n n JAXB creates a parser that is specific to your DTD n n They will parse any well-structured XML A JAXB parser will parse only valid XML (as defined by your DTD) DOM and JAXB both produce a tree in memory n n DOM produces a generic tree; everything is a Node JAXB produces a tree of Objects with names and attributes as described by your DTD

Advantages and disadvantages n Advantages: n JAXB requires a DTD n n n Using JAXB ensures the validity of your XML A JAXB parser is actually faster than a generic SAX parser A tree created by JAXB is smaller than a DOM tree It’s much easier to use a JAXB tree for application-specific code You can modify the tree and save it as XML Disadvantages: n JAXB requires a DTD n n You must do additional work up front to tell JAXB what kind of tree you want it to construct n n Hence, you cannot use JAXB to process generic XML (for example, if you are writing an XML editor or other tool) But this more than pays for itself by simplifying your application JAXB is new: Version 1. 0 dates from Q 4 (fourth quarter) 2002

How JAXB works n JAXB takes as input two files: your DTD and a binding schema (which you also write) n n JAXB produces as output Java source code which you compile and add to your program n n A binding schema is an XML document written in a “binding language” defined by JAXB (with extension. xjs) A binding schema is used to customize the JAXB output Your binding schema can be very simple or quite complex Your program will uses the specific classes generated by JAXB Your program can then read and write XML files JAXB also provides an API for working directly with XML Some examples in this lecture are taken from the JAXB User’s guide, http: //java. sun. com/xml/jaxb/docs. html

A first example n n n The DTD: <!ELEMENT book (title, author, chapter+) > title (#PCDATA) > author (#PCDATA)> chapter (#PCDATA) > The schema: <xml-java-binding-schema> <element name="book" type="class" root="true" /> </xml-java-binding-schema> Note 1: In these slides we only show the class The results: public Book(); // constructor outline, but JAXB public String get. Title(); creates a complete class public void set. Title(String x); for you public String get. Author(); public void set. Author(String x); List get. Chapter(); void delete. Chapter(); void empty. Chapter(); Note 2: JAXB constructs names based on yours, with good capitalization style

Adding complexity n Adding a choice can reduce the usefulness of the parser n n n <!ELEMENT book (title, author, (prologue | preface), chapter+)> <!ELEMENT prologue (#PCDATA) > <!ELEMENT preface (#PCDATA) > With the same binding schema, this gives: n public Book(); public List get. Content(); public void delete. Content(); public void empty. Content(); An improved binding schema can give better results

Improving the binding schema n n <xml-java-binding-schema> <element name="book" type="class" root="true"> <content> <element-ref name="title" /> <element-ref name="author” /> <choice property="prologue-or-preface" /> </content> </element> </xml-java-binding-schema> Result is same as the original, plus methods for the choice: n public. . . public Book(); // constructor void empty. Chapter(); Marshallable. Object get. Prologue. Or. Preface(); void set. Prologue. Or. Preface(Marshallable. Object x);

Marshalling n n n marshal, v. t. : to place or arrange in order marshalling: the process of producing an XML document from Java objects unmarshalling: the process of producing a content tree from an XML document JAXB only allows you to unmarshal valid XML documents JAXB only allows you to martial valid content trees into XML

Limitations of JAXB n JAXB only supports DTDs and a subset of XML Schemas n n Later versions may support more schema languages JAXB does not support the following legal DTD constructs: n n Internal subsets NOTATIONs ENTITY and ENTITIES Enumerated NOTATION types

A minimal binding schema n n A JAXB binding schema is itself in XML Start with: <xml-java-binding-schema version="1. 0 ea"> n n n The version is optional “ea” stands for “early access, ” that is, not yet released Put in: <element name="root. Name" type="class" root="true" /> for each possible root element n n n An XML document can have only one root However, the DTD does not say what that root must be Any top-level element defined by the DTD may be a root The value of name must match exactly with the name in the DTD End with: </xml-java-binding-schema>

More complex schemata n n JAXB requires that you supply a binding schema As noted on the previous slide, this would be <xml-java-binding-schema version="1. 0 ea"> <element name="root. Name" type="class" root="true" /> </xml-java-binding-schema> n With this binding schema, JAXB uses its default rule set to generate your “bindings” n n A binding is an association between an XML element and the Java code used to process that element By adding to this schema, you can customize the bindings and thus the generated Java code

Default bindings, I n A “simple element” is one that has no attributes and only character contents: n n <!ELEMENT element. Name (#PCDATA) > For simple elements, JAXB assumes: <element name="element. Name" type="value"/> n JAXB will treat this element as an instance variable of the class for its enclosing element n This is the default binding, that is, this is what JAXB will assume unless you tell it otherwise n n n For example, you could write this yourself, but set type="class" For simple elements, JAXB will generate these methods in the class of the enclosing element: void set. Element. Name(String x); String get. Element. Name(); We will see later how to convert the #PCDATA into some type other than String

Default bindings, II n n n If an element is not simple, JAXB will treat it as a class Attributes and simple subelements are treated as instance variables DTD: <!ELEMENT element. Name (sub. Element 1, sub. Element 2) > <!ATTLIST element. Name attribute. Name CDATA #IMPLIED> Binding: <element name="element. Name" type="class"> <attribute name="attribute. Name"/> <content> <element-ref name="sub. Element 1" /> <!-- simple element --> <element-ref name="sub. Element 2" /> <!-- complex element --> </content> </element> Java: class Element. Name extends Marshallable. Object { void set. Attribute. Name 1(String x); String get. Attribute. Name 1(); String get. Sub. Element 1(); void set. Sub. Element 1(String x); // Non-simple sub. Element 2 is described on the next slide

Default bindings, III n n If an element contains a subelement that is defined by a class, the code generated will be different <element name="element. Name" type="class"> <content> <element-ref name="sub. Element 2" /> <!-- Note that "element-ref" means this is a reference to an element that is defined elsewhere, not the element itself --> </content> </element> n Results in: class Element. Name extends Marshallable. Object { Sub. Element 2 get. Sub. Element 2(); void set. Sub. Element 2(Sub. Element 2 x); . . . } n Elsewhere, the DTD definition for sub. Element 2 will result in: class Sub. Element 2 extends Marshallable. Object {. . . }

Default bindings, IV n A simple sequence is just a list of contents, in order, with no + or * repetitions n n n Example: <!ELEMENT html (head, body) > For an element defined with a simple sequence, setters and getters are created for each item in the sequence If an element’s definition isn’t simple, or if it contains repetitions, JAXB basically “gives up” and says “it’s got some kind of content, but I don’t know what” n n Example: <!ELEMENT book (title, forward, chapter*)> Result: public Book(); // constructor public List get. Content(); // "general content"--not too useful! public void delete. Content(); public void empty. Content();

Customizing the binding schema n You won’t actually see these default bindings anywhere-they are just assumed n n n If a default binding is OK with you, don’t do anything If you don’t like a default binding, just write your own Here’s the minimal binding you must write: <xml-java-binding-schema> <element name="root. Element" type="class" root="true" /> </xml-java-binding-schema> n Start by “opening up” the root element: <xml-java-binding-schema> <element name="root. Element" type="class" root="true" > </element> </xml-java-binding-schema> n Now you have somewhere to put your customizations

Primitive attributes n By default, attributes are assumed to be Strings n n n <!ATTLIST some. Element some. Attribute CDATA #IMPLIED> class Some. Element extends Marshallable. Object { void set. Some. Attribute(String x); String get. Some. Attribute(); You can define your own binding and use the convert attribute to force the defined attribute to be a primitive, such as an int: n n <element name="some. Element " type="class" > <attribute name="some. Attribute" convert="int" /> </element> class Some. Element extends Marshallable. Object { void set. Some. Attribute(int x); int get. Some. Attribute();

Conversions to Objects, I n At the top level (within <xml-binding-schema>), add a conversion declaration, such as: n n Add a convert attribute where you need it: n n <element name="name" type="value" convert="Big. Decimal" /> The result should be: n n <conversion name="Big. Decimal" type="java. math. Big. Decimal" /> n name is used in the binding schema n type is the actual class to be used public java. math. Big. Decimal get. Name(); public void set. Name(java. math. Big. Decimal x); This works for Big. Decimal because it has a constructor that takes a String as its argument

Conversions to Objects, II n There is a constructor for Date that takes a String as its one argument, but this constructor is deprecated n n This is because there are many ways to write dates For an object like this, you need to supply methods to “parse” and “print” <conversion name="My. Date" type="java. util. Date” parse="My. Date. parse. Date" print="My. Date. print. Date"/> Your class, My. Date, would extend Date and provide parse. Date and print. Date methods

Creating enumerations n n <!ATTLIST shirt size (small | medium | large) #IMPLIED> defines an attribute of shirt that can take on one of a predefined set of values A typesafe enum is a class whose instances are a predefined set of values To create a typesafe enum for size: n <enumeration name="shirt. Size" members="small medium large"> n <element name="shirt". . . > <attribute name="size" convert="shirt. Size" /> </element> You get: n public final class Shirt. Size { public final static Shirt. Size SMALL; public final static Shirt. Size MEDIUM; public final static Shirt. Size LARGE; public static Shirt. Size parse(String x); public String to. String(); }

Content models n The <content> tag describes one of two kinds of content models: n n A general-content property binds a single property n You’ve seen this before: <content property="my-content" /> n Gives: public List get. My. Content(); public void delete. My. Content(); public void empty. My. Content(); A model-based content property can contain four types of declarations: n element-ref says that this element contains another element n choice says that there alternative contents n sequence says that contents must be in a particular order n rest can be used to specify any kind of content

Using JAXB n n JAXB is not currently a part of the standard Java distributions The steps involved in using JAXB are: n n n Download, install, and configure JAXB Write a JAXB schema to describe the bindings you want for your XML Use JAXB to read the JAXB schema and the XML DTD (or XML Schema) and produce Java code Add the Java code to your program and compile it Use the resultant program to: n n Read and validate XML input files Modify the XML tree Optionally validate and output the modified XML Note: Validation is optional and can be performed during unmarshalling or any time thereafter

The End
- Slides: 23