Showing posts with label jaxb. Show all posts
Showing posts with label jaxb. Show all posts

Monday, 21 March 2011

Create XSD file with JAXB

I have explained, generating java classes from xsd. But now it reverse. Then we did xml serialization. But how to generate xsd?

In order to do this, add to your Java project (described in previous 2 articles) the following method:

public void generateSchema(String suggestedSchemaName) throws Exception
{
final File parentFolder = new File(".");
final String schemaName = suggestedSchemaName;

JAXBContext jc = JAXBContext.newInstance(Graph.class);
jc.generateSchema(new SchemaOutputResolver() {
@Override
public Result createOutput(String namespace, String schema) throws IOException {
return new StreamResult(new File(parentFolder, schemaName));
}
});
}


As you can see, JAXBContext class has the generateSchema method, which takes an instance of a SchemaOutputResolver class, that needs to override the createOutput method in order to output the XSD file. So you can afterwards call the method presented above as follow:

generateSchema(“graphXmlSchema.xsd”); 

More on XML serialization with JAXB

I posted some days ago an article explaining how to “XML-serialize” objects with JAXB in Eclipse. The downside of using XSD for XML serialization is the dependency on the XML schema that will generate java classes; this is because I wanted to extend the classes to have extra-functionality, more constructors and so on. So I started looking for a way to serialize objects to XML without creating XSD definitions… but I found a problem: every time java classes are generated, an additional class, called ObjectFactory.java is also created. It is also needed for XML marshalling/unmarshalling. The only viable solution I found was to write my one ObjectFactory.java class, to be used by JAXB when serializing objects.

But I creating ObjectFactory is not necessary. We can simply serialize from simple xml files(see here).

But if we want we can create our own ObjectFactory Class. Example:

Step 1: Create the java classes that you need. In my case, I had two main entities, Node and Line, and two additional collections, Lines and Nodes. I also created a Graph entity, holding a list with nodes and a list with lines. Below are presented Line.java, Lines.java and Graph.java files

Line.java

package com.vaani.jaxb.objects;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Line", propOrder = { "startNode", "endNode" })
public class Line {

@XmlAttribute(name = "StartNode")
protected int startNode;
@XmlAttribute(name = "EndNode")
protected int endNode;

public Line(int start, int end) {
this.setStartNode(start);
this.setEndNode(end);
}

public Line() {
this(0, 0);
}

public int getStartNode() {
return startNode;
}

public void setStartNode(int value) {
this.startNode = value;
}

public int getEndNode() {
return endNode;
}

public void setEndNode(int value) {
this.endNode = value;
}

}


Lines.java

package com.vaani.jaxb.objects;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "lines", propOrder = { "lines" })
public class Lines {

@XmlElement(name = "Line")
protected List<Line> lines;

public List<Line> getLines() {
if (lines == null) {
lines = new ArrayList<Line>();
}
return this.lines;
}
}



Graph.java

package com.vaani.jaxb.objects;

import java.io.*;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Graph")
public class Graph {

@XmlElement(name = "Nodes", required = true)
protected Nodes nodes = new Nodes();
@XmlElement(name = "Lines", required = true)
protected Lines lines = new Lines();
@XmlAttribute(name = "StartNode")
protected int startNode;
@XmlAttribute(name = "EndNode")
protected int endNode;

public void addNode(int x, int y) {
getNodes().add(new Node(x, y, getNodes().size() + 1));
}

public void addLine(int start, int end) {
getLines().add(new Line(start, end));
}

public List<Node> getNodes() {
return nodes.getNodes();
}

public void setNodes(Nodes value) {
this.nodes = value;
}

public List<Line> getLines() {
return lines.getLines();
}

public void setLines(Lines value) {
this.lines = value;
}

public int getStartNode() {
return startNode;
}

public void setStartNode(int value) {
this.startNode = value;
}

public int getEndNode() {
return endNode;
}

public void setEndNode(int value) {
this.endNode = value;
}

public void marshalToFile(String fileName) {
try {
JAXBContext jc = JAXBContext.newInstance(this.getClass().getPackage().getName());
Marshaller m = jc.createMarshaller();
m.marshal( this, new FileOutputStream(fileName) );
} catch(Exception e) {
e.printStackTrace();
}
}

public static Graph unmarshalFromFile(String fileName) {
try {
JAXBContext jc = JAXBContext.newInstance((new Graph()).getClass().getPackage().getName());
Unmarshaller um = jc.createUnmarshaller();
return (Graph) um.unmarshal(new File(fileName));
} catch (Exception e) {
return new Graph();
}
}


}


In order to be able to serialize the above classes, we must use the XML annotations like @XmlRootElement, @XmlElement, @XmlAttribute, @XmlType. For the serialization, we use the same JAXBContext, Marshaller and Unmarshaller classes.

Step 2: Implement the ObjectFactory.java class

package com.vaani.jaxb.objects;

import javax.xml.bind.annotation.XmlRegistry;

@XmlRegistry
public class ObjectFactory {

public ObjectFactory() {
}

public Graph createGraph() {
return new Graph();
}

public Node createNode() {
return new Node();
}

public Line createLine() {
return new Line();
}

}


As you can see, the class must be preceded by @XmlRegistry annotation.

Step 3: Test the serialization

package com.vaani.jaxb.objects;

import org.junit.*;
import static org.junit.Assert.*;

public class GraphTest {

Graph graph;

@Test
public void test_graph()
{
createGraph();
graph.marshalToFile("newGraphOutput.xml");
Graph secondGraph = Graph.unmarshalFromFile("newGraphOutput.xml");
assertTrue(secondGraph.getLines().size() == 2);
assertTrue(secondGraph.getNodes().size() == 3);
}

private void createGraph()
{
graph = new Graph();
graph.addNode(60, 60);
graph.addNode(110, 110);
graph.addNode(60, 110);
graph.addLine(1, 3);
graph.addLine(2, 3);
}
}


Step 4: Check the result

image

Jaxb : Shortcomings of API


JAXB has some shortcomings. Client apps can't customize the marshalling behavior very much. The only standard options are (1) setting the encoding to be used, (2) turn on/off indentation, and (3) add xsi:schemaLocation/xsi:noNamespaceSchemaLocation. You can't even specify how a document should be indented. While you can always plug in some other XML writer, it's not as easy as the rest of JAXB. It would have been easier if Java had a reusable XML writer, like the one in Microsoft .NET. Then the JAXB API could have been designed to work with it.
Further, the ValidationEventHandler interface handles errors during unmarshalling, validation, and marshalling, and ValidationEvent objects represent error information. The problem is that you can't throw ValidationEvent, because it's not throwable. If you compare this with SAX, where you often throw SAXParseException from your ErrorHandler, this is a big difference. I don't claim that the SAX's way is better, but you have to learn yet another way of handling errors.

Marshalling : Jaxb


A Marshaller is used to write an object graph into XML. To write an object o to a file, you would do
Marshaller marshaller = context.createMarshaller();
marshaller.marshal( o, new FileOutputStream("foo.xml") );
There are other overloaded versions which allow you to produce XML as a a DOM tree or as SAX events. For example, by using StringWriter, you can marshal an object into a string. You can also marshal an object graph to a javax.xml.transform.Result object.
In the previous version of JAXB, this functionality was provided as a method on the generated class, and the number of formats was limited. Making it a separate interface enables mapping of existing classes to XML in the future.
In the previous version of JAXB, there was no provision for controlling the formatting. In the new API, you can control the behavior of marshalling by setting Marshaller properties. For example, you can toggle indentation of the XML. More importantly, the mechanism is extensible, which means JAXB providers can expose advanced features.
Although you can customize the behavior of marshalling to some degree by using this mechanism, there's a good chance it doesn't fill your needs completely. For example, some people might want to use tabs for indentation and others might prefer spaces. In some schemas, certain elements cannot be indented without changing the meaning. You might want to control the namespace prefixes. Or you might want to add a processing instruction to the document. In addition, relying on vendor-specific properties compromises portability.
The new version of JAXB can produce XML as SAX events. That is, you can pass ContentHandler and have it receive SAX events from a JAXB object. This gives client apps plenty of chances to modify XML. For example, you can add and remove elements or attributes, use one of the freely available serializers ( XMLWriter by David Megginson, org.apache.xml.serialize.XMLSerializer) for better output, or write your own XML serializer that prints XML in your preferred way.
Finally, you can ask a Marshaller to marshal an invalid object graph by setting a ValidationEventHandler. If a provider supports error recovery, you can tell it to write XML even if it's incomplete.

Jaxb : Validation


JAXB also has the capability to validate an object graph in memory without actually writing it to XML. This allows client apps to check if a graph is okay and ready to process; if not, validation will identify objects that contain errors so that, for example, client apps can ask users to fix those.
The following code validates the object "o".
Validator v = context.createValidator();
if(!v.validate(o)) System.err.println("error");
To receive detailed information about errors, you need to register ValidationEventHandler with the Validator, just like you did in Unmarshaller and Marshaller. This is analogous to registering an ErrorHandler for a SAX parser.
You can also first marshal an object graph and then validate XML (for example by Java API for validators). But doing so makes it much harder to associate errors with their sources, which makes debugging harder for humans. Validation after marshalling will give you errors like "missing <foo> element," but you can hardly know what is actually wrong in the object graph.
Validity is not enforced while you are modifying an object graph; you always have to explicitly validate it. To edit a valid object graph into another valid object graph, you may need to go through invalid intermediate states. If validity is enforced on every step of mutation, this becomes impossible.

UnMarshalling : Jaxb


An unmarshaller is used to read XML and build an object tree from classes generated by the compiler. To read an XML file, you would simply do
Unmarshaller unmarshaller = context.createUnmarshaller();
MyObject o = (MyObject)unmarshaller.unmarshal(new File("foo.xml"));
There are other overloaded versions that take different types of input, such as InputStream or InputSource. You can even unmarshal a javax.xml.transform.Source object. All in all, it's similar to the way DOM trees are parsed.
In the previous version of JAXB, this functionality was provided as a method on the generated class. Since one cannot add methods to existing classes, this design made it impossible to unmarshal them. By moving it into a separate Unmarshaller interface, the new API makes it possible to support this in a future version.
JAXB also supports unmarshalling via a SAX ContentHandler. You can send SAX events to the unmarshaller and have it unmarshal objects. This enhances the connectivity of the Unmarshaller considerably. For example, you can parse the header of a message by using JAXB and send the body of the message to another component. With ContentHandler support, this can be done efficiently.
By default, Unmarshaller is very forgiving. Even if a document is invalid, it tries to recover from errors. If the document is so broken that it cannot be read, an UnmarshalException will be thrown.
It's often desirable to get more information about errors or reject documents with errors. The first step to do this is to set ValidationEventHandler to the Unmarshaller. A ValidationEventHandler can explicitly tell a JAXB implementation whether it should reject a document or try to recover from errors. It also gives you more information, such as line numbers, about errors.
An Unmarshaller can validate a document with the schema while unmarshalling. With this option turned on, it rejects anything short of a valid document. However, W3C XML Schema validation can be very costly.
Another possibility is to set up a SAX pipeline in such a way that your XML parser does the validation; alternately, you could install a stand-alone validator in the pipeline (such as JARV: validation API). In this way, for example, you can change your schema to change what you get from the compiler, while maintaining the scrutiny of the original schema.

Jaxb : TABLE OF CONTENTS

Jaxb : Binding XML Schemas


This section describes the default XML-to-Java bindings used by JAXB. All of these bindings can be overridden on global or case-by-case levels by means of a custom binding declaration.

Simple Type Definitions

A schema component using a simple type definition typically binds to a Java property. Since there are different kinds of such schema components, the following Java property attributes (common to the schema components) include:
  • Base type
  • Collection type, if any
  • Predicate
The rest of the java property attributes are specified in schema component using simple type definition.

Default Data Type Bindings


The Java language provides a richer set of data type than XML schema.
XML Schema TypeJava Data Type
xsd:stringjava.lang.String
xsd:integerjava.math.BigInteger
xsd:intint
xsd.longlong
xsd:shortshort
xsd:decimaljava.math.BigDecimal
xsd:floatfloat
xsd:doubledouble
xsd:booleanboolean
xsd:bytebyte
xsd:QNamejavax.xml.namespace.QName
xsd:dateTimejava.util.Calendar
xsd:base64Binarybyte[]
xsd:hexBinarybyte[]
xsd:unsignedIntlong
xsd:unsignedShortint
xsd:unsignedByteshort
xsd:timejava.util.Calendar
xsd:datejava.util.Calendar
xsd:anySimpleTypejava.lang.String


Default Binding Rules


The JAXB binding model follows the default binding rules summarized below:
FromTo
XML Namespace URIJava package
Named complex typeJava content interface
Anonymous inlined type definition of an element declarationJava content interface
A named simple type definition with a basetype that derives from "xsd:NCName" and has enumeration facetenum class
A global element declaration to a Element interfaceJava Element interface
Local element declaration that can be inserted into a general content listJava Element interface
AttributeJava property

Prerequisites for jaxb

  • Download and install the Java Web Services Developer Pack (Java WSDP) currently at version 2.0 from Sun Microsystem. The Java WSDP is a free, integrated toolkit that allows Java developers to build, test, and deploy XML applications, Web services, and Web applications. Assume that you install JWSDP to C:\jwsdp-2.0 directory.
  • Create a C:\jaxb_samples directory on your machine.
  • For occasional developers, it is convenient to set these variables in a batch file that you run every time you open a command-prompt window. Alternatively, these settings can be permanently added to the command-prompt shortcut. Here is what you should add to a “jaxbsetup.bat” file in C:\jaxb_samples directory (note that only “set” commands are in this listing, any line that doesn’t start with “set” is a continuation of the previous line): set JWSDP_HOME=C:\jwsdp-2.0
    set JWSDP_JAXB_LIB=%JWSDP_HOME%\jaxb\lib
    set JWSDP_SHARED_LIB=%JWSDP_HOME%\jwsdp-shared\lib
    set JWSDP_SJSXP_LIB=%JWSDP_HOME%\sjsxp\lib
    set CLASSPATH=%JWSDP_JAXB_LIB%\jaxb-api.jar;
                  %JWSDP_JAXB_LIB%\jaxb-impl.jar;
                  %JWSDP_JAXB_LIB%\jaxb1-impl.jar;
                  %JWSDP_JAXB_LIB%\jaxb-xjc.jar;%CLASSPATH%
    set CLASSPATH=%JWSDP_SJSXP_LIB%\sjsxp.jar;
                  %JWSDP_SJSXP_LIB%\jsr173_api.jar;%CLASSPATH%
    set CLASSPATH=%JWSDP_SHARED_LIB%\activation.jar;
                  %JWSDP_SHARED_LIB%\resolver.jar;%CLASSPATH%
    set PATH=
    %JWSDP_HOME%\jaxb\bin;%JWSDP_HOME%\jwsdp-shared\bin;%PATH%
  • Copy %JWSDP_HOME%\jaxb\samples\create-marshal directory to jaxb_smaple directory. (Note: we  will not use ant to build this project in here. You can delete build.xml file).

  • Create a subdirectory called classes under jaxb_sample\create-marshal.
Case when JWSDB doesn't get installed 
In this case first try to trouble shoot why it is not getting installed. Because it installs all the necessary jars into JDK like jaxb, saaj, jaxp,jaxrc, etc.

But if not then download jaxb from here. And then add this jar to Eclipse project as external jar.

JAXB : Generating java classes from xsd

Lets first get the xsd file from which we want to generate a java class:
1. Get the following xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>


<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>


<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>


2. Open the command prompt and type xjc … if you get lots of messages that means you have xjc in it, otherwise you have to set it.

3. Generate the java class:

Let the xsd name above is bidding.xsd…Now in the command prompt type:

xjc -p com.vaani.generated -d src bidding.xsd

So xjc is our compiler, -p = package name…so our package name is com.vaani.generated
-d = src is the generated codes outputing directory name.

So the output is :

parsing a schema...
compiling a schema...
com\vaani\generated\Items.java
com\vaani\generated\ObjectFactory.java
com\vaani\generated\PurchaseOrderType.java
com\vaani\generated\USAddress.java

A factory class (ObjectFactory.java), consisting of methods to create instance objects, also gets generated.

 

Taking a look at the generated classes :


package com.vaani.generated;
//
import java.math.BigDecimal;
import javax.xml.bind.annotation.AccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import primer.po.USAddress;


@XmlAccessorType(AccessType.FIELD)
@XmlType(name = "USAddress", propOrder = {
"name",
"street",
"city",
"state",
"zip"
})
public class USAddress {

protected String name;
protected String street;
protected String city;
protected String state;
protected BigDecimal zip;
@XmlAttribute
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String country;

public String getName() {
return name;
}

public void setName(String value) {
this.name = value;
}

public String getStreet() {
return street;
}

public void setStreet(String value) {
this.street = value;
}

public String getCity() {
return city;
}

public void setCity(String value) {
this.city = value;
}

public String getState() {
return state;
}

public void setState(String value) {
this.state = value;
}

public BigDecimal getZip() {
return zip;
}

public void setZip(BigDecimal value) {
this.zip = value;
}

public String getCountry() {
if (country == null) {
return "US";
} else {
return country;
}
}

public void setCountry(String value) {
this.country = value;
}

}

See the eclipse project based on this.

Sunday, 20 March 2011

Jaxb - Example to generate xml from java class

JAXB uses annotations to indicate the central elements.
Following are the annotations used in jaxb:
@XmlRootElement(namespace = "namespace")
Define the root element for a XML tree
@XmlType(propOrder = { "field2", "field1",.. })
Allows to define the order in which the fields are written in the XML file
@XmlElement(name = "neuName")
Define the XML element which will be used. Only need to be used if the neuNeu is different then the JavaBeans Name.
 

Using the Annotations

Step 1 : Create a project in eclipse called SampleJaxb
Now create a Book class:
package com.vaani.xml.jaxb;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "book")
// If you want you can define the order in which the fields are written
// Optional
@XmlType(propOrder = { "author", "name", "publisher", "isbn" })
public class Book {

private String name;
private String author;
private String publisher;
private String isbn;

// If you like the variable name, e.g. "name", you can easily change this
// name for your XML-Output:
@XmlElement(name = "bookName")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public String getPublisher() {
return publisher;
}

public void setPublisher(String publisher) {
this.publisher = publisher;
}

public String getIsbn() {
return isbn;
}

public void setIsbn(String isbn) {
this.isbn = isbn;
}

}


Now we have our book store:

package com.vaani.xml.jaxb;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

//This statement means that class "Bookstore.java" is the root-element of our example
@XmlRootElement(namespace = "com.vaani.xml.jaxb")
public class Bookstore {

// XmLElementWrapper generates a wrapper element around XML representation
@XmlElementWrapper(name = "bookList")
// XmlElement sets the name of the entities
@XmlElement(name = "book")
private ArrayList<Book> bookList;
private String name;
private String location;

public void setBookList(ArrayList<Book> bookList) {
this.bookList = bookList;
}

public ArrayList<Book> getBooksList() {
return bookList;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}
}



The runner class to generate this xml file (we will generate as well print it on console) :

package com.vaani.jaxb.runner;

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 com.vaani.jaxb.Book;
import com.vaani.jaxb.Bookstore;


public class BookMain {

private static final String BOOKSTORE_XML = "./bookstore-jaxb.xml";

public static void main(String[] args) throws JAXBException, IOException {

ArrayList<Book> bookList = new ArrayList<Book>();

// create books
Book book1 = new Book();
book1.setIsbn("978-0060554736");
book1.setName("You can win");
book1.setAuthor("Shiv Khera");
book1.setPublisher("Harpercollins");
bookList.add(book1);

Book book2 = new Book();
book2.setIsbn("978-3832180577");
book2.setName("The monk who sold his Ferrari");
book2.setAuthor("Robin Sharma");
book2.setPublisher("Dumont Buchverlag");
bookList.add(book2);

// create bookstore, assigning book
Bookstore bookstore = new Bookstore();
bookstore.setName("Wordsworth Bookstore");
bookstore.setLocation("Mumbai Airport");
bookstore.setBookList(bookList);

// create JAXB context and instantiate marshaller
JAXBContext context = JAXBContext.newInstance(Bookstore.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
//print xml to console
m.marshal(bookstore, System.out);


Writer w = null;
try {
w = new FileWriter(BOOKSTORE_XML);
//print xml to file
m.marshal(bookstore, w);
} finally {
try {
w.close();
} catch (Exception e) {
}
}

// get variables from our xml file, created before
System.out.println();
System.out.println("Output from our XML File: ");
Unmarshaller um = context.createUnmarshaller();
Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader(
BOOKSTORE_XML));

for (int i = 0; i < bookstore2.getBooksList().toArray().length; i++) {
System.out.println("Book " + (i + 1) + ": "
+ bookstore2.getBooksList().get(i).getName() + " from "
+ bookstore2.getBooksList().get(i).getAuthor());
}

}
}




Now the generated output is :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:bookstore xmlns:ns2="com.vaani.jaxb">
<bookList>
<book>
<author>Shiv Khera</author>
<bookName>You can win</bookName>
<publisher>Harpercollins</publisher>
<isbn>978-0060554736</isbn>
</book>
<book>
<author>Robin Sharma</author>
<bookName>The monk who sold his Ferrari</bookName>
<publisher>Dumont Buchverlag</publisher>
<isbn>978-3832180577</isbn>
</book>
</bookList>
<location>Mumbai Airport</location>
<name>Wordsworth Bookstore</name>
</ns2:bookstore>

Output from our XML File:
Book 1: You can win from Shiv Khera
Book 2: The monk who sold his Ferrari from Robin Sharma

JAXB Architecture

The topics in this section include:

  • Architectural Overview
  • The JAXB Binding Process
  • JAXB Binding Framework
  • More About javax.xml.bind
  • More About Unmarshalling
  • More About Marshalling
  • More About Validation

image

JAXB Introduction

THE Java™ Architecture for XML Binding (JAXB) is a Java technology that enables you to generate Java classes from XML schemas. As part of this process, JAXB also provides methods for unmarshalling XML instance documents into Java content trees, and then marshalling Java content trees back into XML instance documents. Put another way, JAXB provides a fast and convenient way to bind XML schemas to Java representations, making it easy for Java developers to incorporate XML data and processing functions in Java applications.

What this all means is that you can leverage the flexibility of platform-neutral XML data in Java applications without having to deal with or even know XML programming techniques. Moreover, you can take advantage of XML strengths without having to rely on heavyweight, complex XML processing models like SAX or DOM. JAXB hides the details and gets rid of the extraneous relationships in SAX and DOM—generated JAXB classes describe only the relationships actually defined in the source schemas. The result is highly portable XML data joined with highly portable Java code that can be used to create flexible, lightweight applications and Web services.