JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Getting Started with JAXB

November 21, 2013 by Mohamed Sanaulla Leave a Comment

There are quite a few APIs out there for processing XML in Java like DOM Parser, SAX Parser, SAX parser to name a few. But there are scenarios and requirements where we have our data in Java beans and we want that data to be transformed into XML or we have some data in XML and we want that to be populated into Java beans. In such scenarios we can still make use of DOM parser or SAX parser or SAX parser but the code written will be more involved. In order to cater to such requirements a new standard was introduced in Java called JAXB which stands for Java Architecture for XML binding. JAXB supports binding Java objects into XML data and XML data into Java objects. As JAXB is a specification there are many implementations of this specification and I am using the one which comes with Java SE reference implementation. (Yes, JAXB is part of Java SE distribution from Java 6.0).

Simple JAXB Tutorial with Example

To show how one can leverage JAXB I have considered a simple example which covers quite a few concepts of JAXB. Let us model the following scenario: A book has a title, list of authors, a publisher, year of publication, number of pages, cost of the book, ISBN, type of binding and list of reviews. Each review consists of the content, the name of the author who posted it, the rating given by them for the book and the date on which this was posted.

Class Diagrams for the Example

The below are the UML Class diagrams for the different classes identified for our example:

Class diagram for Book class
JAXB Class Diagram

Class diagram for Review class
JAXB Class Diagram1

Class diagram for Books class
Books class

Class diagram for Binding Enum
Binding Enum

Class diagram for Rating Enum
Rating enum

And the class diagram showing the relationship between the classes is:
Class diagram

Now that the classes have been identified, let me give some overview of JAXB API and the annotations it supports.

Overview of JAXB

JAXB provides a mechanism to convert the data in Java objects into XML which is called marshalling and from XML into Java objects which is called Unmarshalling. It requires a XML Schema definition (XSD) to facilitate the generation of XML and validation of XML to generate Java objects. This is taken care by the tools provided by the JAXB and the annotations declared on the java beans. Lets look at the different annotations supported which are used in this example:

Annotation Description
@XmlElement Maps a non static and non transient attribute or a getter to an XML element.
@XmlEnum Maps an Enum to an XML element
@XmlEnumValue Provides a value for Enum to be used in the XML.
@XmlRootElement This annotation is used for any class which would become the root XML Element

There are quite a few other JAXB annotations, but in this example I will be using the above annotations only. There is much detailed tutorial on how the complete JAXB schema generation works, how these annotations get mapped to XML Schema and other advanced aspects of JAXB.

Defining the Classes

Now lets define the classes and annotate them with corresponding JAXB annotations. There can be 2 possible root elements for the XML we are going to generate- book or books. The latter is the root when there are multiple book entries in the XML and the former is the root when we are showing the XML for single book.

Review class

Lets look at the definition for our Review class. The review class is used to model the user comments on a given book and contains the content of the comment, rating given and the date on which it was posted.

[code lang=”java”]
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.annotation.XmlElement;

/**
* Represents the user comment on some item.
* This is not annotated as @XMLRootElement as we dont expect this to be used
* as a root of XML.
*/
public class Review {
public String content;
public Rating rating;
public String author;
private Date postedOn;

public Review(String content, String author, Date postedOn, Rating rating) {
this.content = content;
this.rating = rating;
this.author = author;
this.postedOn = postedOn;
}

/**
* Returns the date formatted using SimpleDateFormat and is used by JAXB
* while generating the XML.
*/
@XmlElement(name="postedOn")
public String getPostedOn(){
SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, ”yy");
return sdf.format(postedOn);
}

/**
* Reformats the date represented in String into a Date instance. This is used
* while JAXB is unmarshalling the XML into Java objects.
*/
public void setPostedOn(String posted) {
SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, ”yy");
try {
this.postedOn = sdf.parse(posted);
} catch (ParseException ex) {
Logger.getLogger(Review.class.getName()).log(Level.SEVERE, null, ex);
}
}

public Review() {
}
}
[/code]

Rating Enum

We use an Enum to provide different rating levels which a user can choose while rating any item. The below code explains the Rating enum;

[code lang=”java”]

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;

/**
* Represents the different levels of rating which a user can give to
* any item.
*/
@XmlEnum(Integer.class)
public enum Rating {
@XmlEnumValue("1") ONE(1),
@XmlEnumValue("2") TWO(2),
@XmlEnumValue("3") THREE(3),
@XmlEnumValue("4") FOUR(4),
@XmlEnumValue("5") FIVE(5);

private Rating(int code) {
this.code = code;
}
public int code;
}
[/code]

Book class

The Book class holds the data associated with a book and its class definition is:

[code lang=”java”]
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

/**
* Represents the data for a Book. Annotated for use with JAXB.
*/
@XmlRootElement
public class Book {

public String title;

@XmlElementWrapper(name="authors")
@XmlElement(name="author")
public List<String> authors;

public String publisher;
public Integer year;
public Integer numberOfPages;
public Double price;

@XmlElementWrapper(name = "reviews")
@XmlElement(name="review")
public List<Review> reviews;

public String isbn;
public Binding binding;

@Override
public String toString(){
return title;
}
}
[/code]

You can see that I have used @XmlElementWrapper annotation. This annotation helps in wrapping a list of child elements into a common parent element. For example in the above example I want all the review XML nodes to be part of the parent reviews XML node.

Binding Enum

Each book can either be hardbound or paperback and this is modeled using an Enum as shown below:

[code lang=”java”]
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;

/**
* Represents the type of binding of the book.
*/
@XmlEnum(String.class)
public enum Binding {
@XmlEnumValue("Paperback") PAPERBACK ("Paperback"),
@XmlEnumValue("Hardcover") HARDCOVER ("Hardcover");

private Binding(String displayString) {
this.displayString = displayString;
}

public String displayString;
}
[/code]

Books class

The Books is used to hold multiple book objects. Its just a container for multiple books as show in the code below:

[code lang=”java”]

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
* Container for multiple books
*/
@XmlRootElement
public class Books{

@XmlElement(name="book")
public List<Book> myBooks = new ArrayList<>();

public void addToBooks(Book book){
myBooks.add(book);
}
public void setBooks(List<Book> bks){
myBooks.addAll(bks);
}
}
[/code]

Marshalling and Unmarshalling XML Data

Now that we have seen all the class definitions let us now see how one can perform marshalling and unmarshalling of XML data. Before that we need to have some data i.e some populated instances of Book class and the below class does the population of test data:

[code lang=”java”]
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import model.Binding;
import model.Book;
import model.BookStock;
import model.Books;
import model.Rating;
import model.Review;

/**
* Class for populating test data.
*/
public class BookDb {

Books books;
Map<String, Book> bookIsbnMap;
Map<Book, BookStock> bookStock;

public static BookDb bookDb = new BookDb();

private BookDb(){

Calendar calendar = Calendar.getInstance();
Date today = calendar.getTime();
calendar.add(Calendar.DATE, -4);
Date olderDay1 = calendar.getTime();
calendar.add(Calendar.DATE, -10);
Date olderDay2 = calendar.getTime();

books = new Books();
bookIsbnMap = new HashMap<>();
Book book = new Book();
book.authors = Arrays.asList("Narasimha Karumanchi");
book.binding = Binding.PAPERBACK;
book.isbn = "9780615459813";
book.numberOfPages = 429;
book.price = 344.0;
book.publisher = "CareerMonk Publications";
book.title = "Data Structures and Algorithms Made Easy 2nd Edition";
book.year = 2011;
book.reviews = (Arrays.asList(new Review("Great book", "Abc Xyz", today ,Rating.FOUR),
new Review("Needs improvement", "Xyz Pqr", olderDay1, Rating.TWO)));

books.addToBooks(book);
bookIsbnMap.put(book.isbn, book);

book = new Book();
book.title = "Java : The Complete Reference 8 Edition";
book.price = 438.0;
book.authors = Arrays.asList("Herbert Schildt");
book.binding = Binding.PAPERBACK;
book.isbn = "9781259002465";
book.numberOfPages = 1152;
book.publisher = "Tata McGraw – Hill Education";
book.year = 2011;
book.reviews = (Arrays.asList(new Review("Great Book!!", "Pqr Wxy", today, Rating.FIVE),
new Review("Must read for Java programmers", "Xyz Abc", olderDay1, Rating.FIVE)));

books.addToBooks(book);
bookIsbnMap.put(book.isbn, book);

}

/**
* Adds the new instance of Book to the database i.e the List of books.
*/
public boolean addToBookDb(Book book){
books.addToBooks(book);
bookIsbnMap.put(book.isbn, book);

return true;
}

/**
* API to obtain the book details given the ISBN number.
*/
public Book getBookByIsbn(String isbn){
return bookIsbnMap.get(isbn);
}

/**
* Returns all the book details stored in the list.
*/
public Books getAllBooks(){
return books;
}
}
[/code]

Marshalling one instance of Book class

In the below code we marshall one instance of Book class into XML data:

[code lang=”java”]
public class JaxbTest {

static BookDb bookDb;
public JaxbTest() {
}

@BeforeClass
public static void setup(){
bookDb = BookDb.bookDb;
}

/**
* Marshalling one instance of Book class.
*/
@Test public void marshalOne() throws JAXBException{
JAXBContext context = JAXBContext.newInstance(Book.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(bookDb.getAllBooks().myBooks.get(0), System.out);

}
}
[/code]

And the output is:

[code lang=”xml”]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
<title>Data Structures and Algorithms Made Easy 2nd Edition</title>
<authors>
<author>Narasimha Karumanchi</author>
</authors>
<publisher>CareerMonk Publications</publisher>
<year>2011</year>
<numberOfPages>429</numberOfPages>
<price>344.0</price>
<reviews>
<review>
<content>Great book</content>
<rating>4</rating>
<author>Abc Xyz</author>
<postedOn>Thu, Nov 21, ’13</postedOn>
</review>
<review>
<content>Needs improvement</content>
<rating>2</rating>
<author>Xyz Pqr</author>
<postedOn>Sun, Nov 17, ’13</postedOn>
</review>
</reviews>
<isbn>9780615459813</isbn>
<binding>Paperback</binding>
</book>
[/code]

Marshalling list of instances of Book class

Above we saw how to marshal one instance of Book class. In this we will see how to marshall a list of Book instances i.e instance of Books class.

[code lang=”java”]
/**
* Unit test to test the Marshalling and Unmarshalling of the
* XML using JAXB APIs.
*/
public class JaxbTest {

static BookDb bookDb;
public JaxbTest() {
}

@BeforeClass
public static void setup(){
bookDb = BookDb.bookDb;
}

/**
* Marshalling list of books i.e instance of Books class.
*/
@Test public void marshalAll() throws JAXBException{
JAXBContext context = JAXBContext.newInstance(Books.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(bookDb.getAllBooks(), System.out);

}
}
[/code]

And the XML generated for the above marshalling will be:

[code lang=”xml”]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books>
<book>
<title>Data Structures and Algorithms Made Easy 2nd Edition</title>
<authors>
<author>Narasimha Karumanchi</author>
</authors>
<publisher>CareerMonk Publications</publisher>
<year>2011</year>
<numberOfPages>429</numberOfPages>
<price>344.0</price>
<reviews>
<review>
<content>Great book</content>
<rating>4</rating>
<author>Abc Xyz</author>
<postedOn>Thu, Nov 21, ’13</postedOn>
</review>
<review>
<content>Needs improvement</content>
<rating>2</rating>
<author>Xyz Pqr</author>
<postedOn>Sun, Nov 17, ’13</postedOn>
</review>
</reviews>
<isbn>9780615459813</isbn>
<binding>Paperback</binding>
</book>
<book>
<title>Java : The Complete Reference 8 Edition</title>
<authors>
<author>Herbert Schildt</author>
</authors>
<publisher>Tata McGraw – Hill Education</publisher>
<year>2011</year>
<numberOfPages>1152</numberOfPages>
<price>438.0</price>
<reviews>
<review>
<content>Great Book!!</content>
<rating>5</rating>
<author>Pqr Wxy</author>
<postedOn>Thu, Nov 21, ’13</postedOn>
</review>
<review>
<content>Must read for Java programmers</content>
<rating>5</rating>
<author>Xyz Abc</author>
<postedOn>Sun, Nov 17, ’13</postedOn>
</review>
</reviews>
<isbn>9781259002465</isbn>
<binding>Paperback</binding>
</book>
</books>
[/code]

Unmarshalling the XML into Java objects

Now lets look at how we can unmarshall the below XML into Java objects.

[code lang=”xml”]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books>
<book>
<title>Cracking The Coding Interview: 150 Programming Questions And Solutions </title>
<authors>
<author>Gayle Laakmann McDowell</author>
</authors>
<publisher>Pothi.com</publisher>
<year>2011</year>
<numberOfPages>508</numberOfPages>
<price>504</price>
<reviews>
<review>
<content>Great book</content>
<rating>4</rating>
<author>Abc Xyz</author>
<postedOn>Mon, Nov 18, ’13</postedOn>
</review>
<review>
<content>Needs improvement</content>
<rating>2</rating>
<author>Xyz Pqr</author>
<postedOn>Thu, Nov 14, ’13</postedOn>
</review>
</reviews>
<isbn>9780984782802</isbn>
<binding>Paperback</binding>
</book>
<book>
<title>Java : The Complete Reference 8 Edition</title>
<authors>
<author>Herbert Schildt</author>
</authors>
<publisher>Tata McGraw – Hill Education</publisher>
<year>2011</year>
<numberOfPages>1152</numberOfPages>
<price>438.0</price>
<reviews>
<review>
<content>Great Book!!</content>
<rating>5</rating>
<author>Pqr Wxy</author>
<postedOn>Mon, Nov 18, ’13</postedOn>
</review>
<review>
<content>Must read for Java programmers</content>
<rating>5</rating>
<author>Xyz Abc</author>
<postedOn>Thu, Nov 14, ’13</postedOn>
</review>
</reviews>
<isbn>9781259002465</isbn>
<binding>Paperback</binding>
</book>
</books>
[/code]

The code which unmarshalls the above XML into Java objects and prints the data to the console:

[code lang=”java”]
/**
* Unit test to test the Marshalling and Unmarshalling of the
* XML using JAXB APIs.
*/
public class JaxbTest {

static BookDb bookDb;
public JaxbTest() {
}

@BeforeClass
public static void setup(){
bookDb = BookDb.bookDb;
}

/**
* Unmarshalling the XML file into an instance of Books class.
*/
@Test public void unMarshalAll() throws JAXBException{
JAXBContext context = JAXBContext.newInstance(Books.class);
Unmarshaller um = context.createUnmarshaller();
Books books = (Books)um.unmarshal(new File("D:\\dev\\my_books.xml"));
for ( Book book : books.myBooks){
System.out.println("Details for: "+book.title);
System.out.println("Author: "+ joinList(book.authors));
System.out.println("ISBN: "+ book.isbn);
System.out.println("Publisher: "+ book.publisher);
System.out.println("Cost: "+book.price);
System.out.println("Publication year: "+book.year);
System.out.println("Reviews: ");
for ( Review review : book.reviews){
System.out.println(review.content+" by "+ review.author+" posted on "+review.getPostedOn());
}
}
}

private String joinList(List<String> list){
StringBuilder builder = new StringBuilder();
for ( String str : list){
builder.append(str).append(",");
}
return builder.toString().substring(0, builder.length()-1);
}
}
[/code]

The output:

[code lang=”shell”]
Details for: Cracking The Coding Interview: 150 Programming Questions And Solutions
Author: Gayle Laakmann McDowell
ISBN: 9780984782802
Publisher: Pothi.com
Cost: 504.0
Publication year: 2011
Reviews:
Great book by Abc Xyz posted on Mon, Nov 18, ’13
Needs improvement by Xyz Pqr posted on Thu, Nov 14, ’13
Details for: Java : The Complete Reference 8 Edition
Author: Herbert Schildt
ISBN: 9781259002465
Publisher: Tata McGraw – Hill Education
Cost: 438.0
Publication year: 2011
Reviews:
Great Book!! by Pqr Wxy posted on Mon, Nov 18, ’13
Must read for Java programmers by Xyz Abc posted on Thu, Nov 14, ’13
[/code]

The complete code for the JUnit test which tests the Marshalling and Unmarshalling features is:

[code lang=”java”]
import db.BookDb;
import java.io.File;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import model.Book;
import model.Books;
import model.Review;
import org.junit.Test;
import org.junit.BeforeClass;

/**
* Unit test to test the Marshalling and Unmarshalling of the
* XML using JAXB APIs.
*/
public class JaxbTest {

static BookDb bookDb;
public JaxbTest() {
}

@BeforeClass
public static void setup(){
bookDb = BookDb.bookDb;
}

/**
* Marshalling one instance of Book class.
*/
@Test public void marshalOne() throws JAXBException{
JAXBContext context = JAXBContext.newInstance(Book.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(bookDb.getAllBooks().myBooks.get(0), System.out);

}

/**
* Marshalling list of books i.e instance of Books class.
*/
@Test public void marshalAll() throws JAXBException{
JAXBContext context = JAXBContext.newInstance(Books.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(bookDb.getAllBooks(), System.out);

}

/**
* Unmarshalling the XML file into an instance of Books class.
*/
@Test public void unMarshalAll() throws JAXBException{
JAXBContext context = JAXBContext.newInstance(Books.class);
Unmarshaller um = context.createUnmarshaller();
Books books = (Books)um.unmarshal(new File("D:\\dev\\my_books.xml"));
for ( Book book : books.myBooks){
System.out.println("Details for: "+book.title);
System.out.println("Author: "+ joinList(book.authors));
System.out.println("ISBN: "+ book.isbn);
System.out.println("Publisher: "+ book.publisher);
System.out.println("Cost: "+book.price);
System.out.println("Publication year: "+book.year);
System.out.println("Reviews: ");
for ( Review review : book.reviews){
System.out.println(review.content+" by "+ review.author+" posted on "+review.getPostedOn());
}
}
}

private String joinList(List<String> list){
StringBuilder builder = new StringBuilder();
for ( String str : list){
builder.append(str).append(",");
}
return builder.toString().substring(0, builder.length()-1);
}
}
[/code]

How To Convert Properties File Into XML File Using Java?

If you have any issues in following and implementing the above example feel free to drop in your issues as comments. I will try to address them at the earliest.

Filed Under: Java Tagged With: javaee 7, JAXB, XML

JAXB Tutorial

October 10, 2013 by Krishna Srinivasan Leave a Comment

This tutorial is introduction to Java Architecture for XML Binding (JAXB). JAXB tutorial is based on the Java 6.0 and later versions. JAXB is XML Binding API which defines the API for reading and writing the XML files from Java objects. As the binding word defines, XML and Java objects are binded together for the easy conversion of data from XML to Java and Java to XML. JAXB API is developed as a separate project outside JDK. Since Java 6.0, it is part of the Java libraries. Java objects are annotated with the suitable annotations to help the JAXB to convert to XML elements. @XmlRootElement, @XmlType and @XmlElement are the few most frequently used annotations.

@XmlRootElement

This is class level annotation. This also can be used with enum type. When this annotation is used for a class or enum, then that class will appear as element in the XML structure. This annotation has two properties name and namespace. Name can be specified if you want to customize the name instead of using the class name. If namespace is specified, that element will be considered as the root element for that XML structure.

@XmlType

This annotation has five properties, among that propOrder is important one for specifying the sequence of the elements to appear in the XML structure. This annotation also will be used with class or enum types.

@XmlElement

@XmlElement annotation can be used with a Javabean property or non-static, non-transient field. When this annotation is used, the bean property is used as the local attribute for a complex type. It has six properties as name, defaultValue,namespace,nillable, required and type. We will create a sample project for demonstrating the above concepts.

  • Xquery Syntax
  • How to Query XML using XPath

As a first step, create a domain model. We are creating Employee.java and Company.java

Example JAXB Tutorial Listing 1 : Employee.java

[code lang=”java”]
package javabeat.net;

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

@XmlRootElement(name="employee")
@XmlType (propOrder={"name","empId","designation","city","country"})
public class Employee {
private String name;
private String empId;
private String designation;
private String city;
private String country;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}

@XmlElement (name="role")
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}

[/code]

Example JAXB Tutorial Listing 2 : Company.java

[code lang=”java”]
package javabeat.net;

import java.util.ArrayList;

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

@XmlRootElement (namespace="org.xml.ns")
public class Company {
private ArrayList<Employee> employees;
private String branchCode;
private String city;
public ArrayList<Employee> getEmployees() {
return employees;
}
public void setEmployees(ArrayList<Employee> employees) {
this.employees = employees;
}
public String getBranchCode() {
return branchCode;
}
public void setBranchCode(String branchCode) {
this.branchCode = branchCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}

[/code]

Create the test client program for executing the JAXB example.

Example JAXB Tutorial Listing 1 : ClientMain.java

[code lang=”java”]
package javabeat.net;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class ClientMain {
private static final String XML_FILE_NAME = "CompanyEmployees.xml";
public static void main (String args[]) throws JAXBException, IOException{
ArrayList<Employee> arrayList = new ArrayList<Employee>();
Employee employee = new Employee();
employee.setName("Krishna");
employee.setEmpId("001");
employee.setDesignation("Software Engineer");
employee.setCity("Bangalore");
employee.setCountry("India");
arrayList.add(employee);
employee = new Employee();
employee.setName("Sanaulla");
employee.setEmpId("002");
employee.setDesignation("Software Engineer");
employee.setCity("Chennai");
employee.setCountry("India");
arrayList.add(employee);

Company company = new Company();
company.setEmployees(arrayList);
JAXBContext jaxbContext = JAXBContext.newInstance(Company.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(company, System.out);
marshaller.marshal(company, new File (XML_FILE_NAME));

Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Company companyObj = (Company) unmarshaller.unmarshal(new FileReader(XML_FILE_NAME));
ArrayList<Employee> list = companyObj.getEmployees();
for (Employee employeeObj : list) {
System.out.println("Employee: " + employeeObj.getName() + " from "
+ employeeObj.getName());
}
}
}
[/code]

If you run the above code, Java objects are created in the XML file using the marshaling, then it is un-marshaled back to the Java objects. It is clear enough to understand yourself if you go through the above example programs. If you have questions on this tutorial, please reach me by submitting your comments. I would be happy to answer all your queries.

Filed Under: Java Tagged With: Java, JAXB

JAXB Exception : nor any of its super class is known to this context

April 3, 2012 by Krishna Srinivasan Leave a Comment

When you are working with the JAXB objects, there are some times you would encounter the exception saying the “nor any of its super class is known to this context”. The reason for this error could be many reasons it depends on the environment you are working. The simple solution for fixing the problem is to add

also read:

  • XML Tutorials
  • How to Parse XML file using DOM Parser?
  • How to Parse XML file using SAX Parser?

[code lang=”java”]
@XmlSeeAlso({ClassName.class})
[/code]
When you are working with the JAXB objects, there are some times you would encounter the exception saying the “nor any of its super class is known to this context”. The reason for this error could be many reasons it depends on the environment you are working. The simple solution for fixing the problem is to add
[code lang=”java”]
@XmlSeeAlso({ClassName.class})
[/code]

element in all the classes generated by the JAXB generator. For example, if you are trying to marshall the java object into the XML file using the following code:
[code lang=”java”]
JAXBContext jaxbContext = JAXBContext     .newInstance("com.request");

   Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

   // output pretty printed

   jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

   RequestClass request = new RequestClass();

   jaxbMarshaller.marshal(requestClass, file);
[/code]
The XML file will be generated base don the RequestClass. All the other files would have to add the @XmlSeeAlso({RequestClass.class}) to avoid this exception. It is only the work around and not the fixed solution for this problem.
element in all the classes generated by the JAXB generator. For example, if you are trying to marshall the java object into the XML file using the following code:
[code lang=”java”]
JAXBContext jaxbContext = JAXBContext     .newInstance("com.request");

   Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

   // output pretty printed

   jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

   RequestClass request = new RequestClass();

   jaxbMarshaller.marshal(requestClass, file);
[/code]
The XML file will be generated base don the RequestClass. All the other files would have to add the @XmlSeeAlso({RequestClass.class}) to avoid this exception. It is only the work around and not the fixed solution for this problem.

Filed Under: XML Tagged With: JAXB

Mapping Java Objects and XML Documents using JAXB in Java 6.0

June 8, 2007 by Krishna Srinivasan Leave a Comment

1) Introduction

JAXB (Java API for XML Binding) technology which was included as part of JWSDP (Java Web Services Developer Pack) before, is now included with the Mustang Distribution. Simply put, it is a Mapping Technology for Java and XML Documents. Using JAXB, one can Generate XML Documents from Java Objects and also they can Construct Java Objects from one or more XML Documents. In JAXB terms, Marshalling refers to the process of converting a Java Object to a XML Document and Un-Marshalling is the reverse of Marshalling which is simply getting a Java Object from one or more XML Documents.

also read:

  • New Features in Java 6.0 – Par 1
  • New Features in Java 6.0 – Par 2
  • Java 6.0 Compiler API

Let us see along with Samples how to work with Marshalling and Un-Marshalling with JAXB.

2) Generating XML Documents from Java Objects

Assume that you want to have a XML Representation of a Java object. Using JAXB Marshalling you can do with much ease and the following Sample Application illustrates the same,
Person.java

[code lang=”java”] package net.javabeat.articles.java6.newfeatures.jaxb;

import java.util.Date;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement()
public class Person {

private String name;
private int age;
private Date dateOfBirth;
private String type;

public Person(){
}

public Person(String name, int age, Date dateOfBirth, String type) {
this.name = name;
this.age = age;
this.dateOfBirth = dateOfBirth;
this.setType(type);
}

@XmlElement()
public String getName() {
return name;
}

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

@XmlElement()
public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@XmlElement()
public Date getDateOfBirth() {
return dateOfBirth;
}

public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}

@XmlAttribute()
public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}
}[/code]
The above Person class has various properties namely ‘name’, ‘age’, ‘dateOfBirth’ and ‘type’ and objects of this Class are the targets we wish to Marshal. The Person class is annotated with @XmlRootElement since we want the name of the Class to be the Root Node. We want ‘name’, ‘age’, and ‘dateOfBirth’ as Child Elements so it has been tagged with @XmlElement. Since we want ‘type’ to appear as an Attribute we had tagged that as @XmlAttribute.
Java2XML.java

[code lang=”java”] package net.javabeat.articles.java6.newfeatures.jaxb;

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

public class Java2XML {

public Java2XML() {
}

public static void main(String args[]) throws Exception{
JAXBContext context = JAXBContext.newInstance(Person.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

Person person = new Person(
"Anonymous", 32, new Date(1970, 1, 10), "employee");
marshaller.marshal(person, new FileWriter(".\\src\\Person.xml"));
}
}[/code]
JAXBContext serves as the Entry Point for making use of the JAXB API. It is initiated by the list of Class objects whose objects want to be represented as XML Documents. Then an instance of Marshaller is created by calling JAXBContext.createMarshaller() method. The Java object of type Person is marshalled into the XML Document by calling the Marshaller.marshall() method. Since we want the XML Document to look Well-indented, we have set the property Marshaller.JAXB_FORMATTED_OUTPUT to true.
A file named Person.xml would have got generated and following is the listing of that file,
Person.xml

[code lang=”xml”] <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person type="employee">
<age>32</age>
<dateOfBirth>1970-01-10 T00:00:00+05:30</dateOfBirth>
<name>Anonymous</name>
</person>[/code]

3) Representing Java Objects from XML Documents

In the previous section, we saw how to generate an XML Document from a Java Object. Now, let us see the Unmarshalling process here. As mentioned, Unmarshalling is the process of representing Java Objects from a XML Document. The process of Unmarshalling is a bit complicated as so many steps are involved. Let us break the steps one by one in greater detail.

3.1) Creating the XML Schema Definition File

If Java Classes represent the templates wherein objects can be created for a particular type, then in XML World, it is the XML Schema Definition File through which XML Document Instances can be instantiated. The first thing before creating a XML Document is to create a XML Schema and then to attach the Schema to a XML Document Instance. Let us look into a sample XML Schema File called Items, which will contain a list of ‘Item’ Elements along with its ‘Name’ and ‘Price’. Following is the listing of that File.
Items.xsd

[code lang=”xml”] <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="Item"/>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="Item">
<xs:complexType>
<xs:sequence>
<xs:element ref="Name"/>
<xs:element ref="Price"/>
</xs:sequence>

<xs:attribute name="id" use="required" type="xs:NCName"/>
</xs:complexType>

</xs:element>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Price" type="xs:string"/>
</xs:schema>[/code]
The above is the XML Schema Definition File which represents a list of Items. Since ‘Items’ element contain a list of Item elements and ‘Item’ element in turn contains both ‘Name’ and ‘Price’ Element, both these elements are Composite Elements and the same is represented by complexType elements.

3.2) Generating Java Files from the Schema Definition Files

Now, its time to generate the Java Source Files from this XML Schema Definition File. Mustang comes with a Utility called xjc (which stands for XML to Java Compiler) which generates Java Source Files when given a XML Schema File. Xjc is nothing but a bat file location in the bin directory of the Java 6 Installation Path. Run the following command to generate the Java Source Files.

[code lang=”java”] xjc –p net.javabeat.articles.java6.newfeatures.jaxb Items.xsd[/code]
The only argument to xjc is the name of the XML Schema File which is represented by Items.xsd and the ‘-p’ option specifies the package to which the generated Java Files have to be associated. This results is the generation of the following source files.
Item.java

[code lang=”java”] package net.javabeat.articles.java6.newfeatures.jaxb;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;
import net.javabeat.articles.java6.newfeatures.jaxb.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"name",
"price"
})
@XmlRootElement(name = "Item")
public class Item {

@XmlElement(name = "Name")
protected String name;
@XmlElement(name = "Price")
protected String price;
@XmlAttribute(required = true)
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String id;

public String getName() {
return name;
}

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

public String getPrice() {
return price;
}

public void setPrice(String value) {
this.price = value;
}

public String getId() {
return id;
}

public void setId(String value) {
this.id = value;
}
}[/code]
This file is just a Data file for the corresponding ‘Item’ element which contains getter and setter methods with properly instructed Annotations. Note that the two sub-elements namely ‘name’ and ‘type’ has been tagged with @XmlElement Annotation and the attribute ‘id’ has been tagged with @XmlAttribute Annotation.
Items.java

[code lang=”java”] package net.javabeat.articles.java6.newfeatures.jaxb;

import java.util.*;
import javax.xml.bind.annotation.*;
import net.javabeat.articles.java6.newfeatures.jaxb.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"item"
})
@XmlRootElement(name = "Items")
public class Items {

@XmlElement(name = "Item")
protected List<Item> item;

public List<Item> getItem() {
if (item == null) {
item = new ArrayList<Item>();
}
return this.item;
}
}[/code]
This is the Container Class for the Item element and it just contains a getter for the Item object. Note how the list of ‘Item’ elements in the Schema Document has been mapped to List of Item (List<Item>) elements. This is the Default Mapping given by the Sun’s Reference Implementation for JAXB.
ObjectFactory.java

[code lang=”java”] package net.javabeat.articles.java6.newfeatures.jaxb;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
import net.javabeat.articles.java6.newfeatures.jaxb.Item;
import net.javabeat.articles.java6.newfeatures.jaxb.Items;
import net.javabeat.articles.java6.newfeatures.jaxb.ObjectFactory;

@XmlRegistry
public class ObjectFactory {

private final static QName _Price_QNAME = new QName("", "Price");
private final static QName _Name_QNAME = new QName("", "Name");

public ObjectFactory() {
}

public Item createItem() {
return new Item();
}

public Items createItems() {
return new Items();
}

@XmlElementDecl(namespace = "", name = "Price")
public JAXBElement<String> createPrice(String value) {
return new JAXBElement<String>(_Price_QNAME, String.class, null, value);
}

@XmlElementDecl(namespace = "", name = "Name")
public JAXBElement<String> createName(String value) {
return new JAXBElement<String>(_Name_QNAME, String.class, null, value);
}

}[/code]
As guessed from its name, this is the Factory Class for creating various elements like ‘Items’, ‘Item’, ‘Name’ and Price’. Appropriate methods are available for creating ‘Items’, ‘Item’, ‘Name’ and ‘Price’ in the form of ObjectFactory.createItems(), ObjectFactory.createItem(), ObjectFactory.createName() and ObjectFactory.createPrice() respectively.

3.3) Creating a Sample XML Document

Now let us create a Sample XML Document against the Schema Definition File Items.xsd. Following is the sample XML file called Items.xml. Note how the XML Document Instance is related with the XML Schema Definition File with the help of ‘xsi:noNamespaceSchemaLocation’ attribute.
Items.xml

[code lang=”java”] <Items xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
xsi:noNamespaceSchemaLocation=’file:C:/Items.xsd’>

<Item id="LAP001">
<Name>Laptop</Name>
<Price>4343$</Price>
</Item>

<Item id="TV001">
<Name>Television</Name>
<Price>433$</Price>
</Item>

<Item id="DVD001">
<Name>DVD Player</Name>
<Price>763$</Price>
</Item>

</Items>
[/code]

3.4) Unmarshalling the XML Document to construct the Java object

The code to Unmarshall the XML Document is given below. The code first represents a JAXBContext object by passing in a Context Path which is usually the package name where the compiled Java Class files are located. Then an Unmarshaller object is created by calling JAXBContext.createUnmarshaller() which does the unmarshalling operation by calling the Unmarshaller.unmarshall() method passing in the XML File. Then the object is iterated over the get the actual data contents from the XML File.
XML2Java.java

[code lang=”java”] package net.javabeat.articles.java6.newfeatures.jaxb;

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

public class XML2Java {

public static void main(String args[]) throws Exception{

JAXBContext context = JAXBContext.newInstance(
"net.javabeat.articles.java6.newfeatures.jaxb");
Unmarshaller unmarshaller = context.createUnmarshaller();
Items items = (Items)unmarshaller.unmarshal(
new FileReader(".\\src\\Items.xml"));
List listOfItems = items.getItem();
for(Item item : listOfItems){
System.out.println("Name = " + item.getName() +
", Price = " + item.getPrice() + ", Id = " + item.getId());
}
}
}[/code]

Following is the output of the above program

[code] Name = Laptop, Price = 4343$, Id = LAP001
Name = Television, Price = 433$, Id = TV001
Name = DVD Player, Price = 763$, Id = DVD001 [/code]

4) Conclusion

This article covered the leftover features of the Part I New features of Java 6. Starting with Pluggable Annotation Processing API, it covered what Annotations are, then guided us how to write Custom Annotations and Custom Annotation Processor. Then it traversed over the Cursor API and the Event Iterator API of StaX such as how to read XML Documents along with well-defined samples. Finally through Java API for XML Binding, it details how to map Java and XML Documents with some sample applications.

Filed Under: Java Tagged With: Java 6.0, JAXB

Java 6.0 Features Part – 2 : Pluggable Annotation Processing API

June 6, 2007 by Krishna Srinivasan Leave a Comment

1) Introduction

The first part of this article listed out the major new features of Java 6 (Mustang) related to areas like Common Annotations (JSR 250), Scripting Language for the Java Platform (JSR 223) and JDBC 4.0. This article assumed that Readers have got sufficiently fair bit of knowledge in the various concepts of Java 5.0. First-time Readers of Java 6 are strongly encouraged to read the first part of this article titled “Introduction to Java 6.0 New Features, Part–I”. This article covers the left-over features of Part-I. More specifically, it will cover the Pluggabable Annotation Processing API (JSR 269), Java API for XML Binding (JSR 222) and Streaming API for XML (JSR 173).

also read:

  • New Features in Java 6.0 – Par 1
  • New Features in Java 6.0 – Par 2
  • Java 6.0 Compiler API

2) Pluggable Annotation Processing API

2.1) Introduction to Annotation

Annotations have been there in the Java World from Java 5.0. Java Annotations are a result of the JSR 175 which aimed in providing a Meta-Data Facility to the Java Programming Language. It can be greatly used by the Build-time Tools and Run-time Environments to do a bunch of useful tasks like Code Generation, Validation and other valuable stuffs. Java 6 has introduced a new JSR called JSR 269, which is the Pluggable Annotation Processing API. With this API, now it is possible for the Application Developers to write a Customized Annotation Processor which can be plugged-in to the code to operate on the set of Annotations that appear in a Source File.
Let us see in the subsequent sections how to write a Java File which will make use of Custom Annotations along with a Custom Annotation Processor to process them.

2.2) Writing Custom Annotations

This section provides two Custom Annotations which will be used by a Sample Java File and a Custom Annotation Processor. One is the Class Level Annotation and the other is the Method Level Annotation. Following is the listing for both the Annotation Declarations. See how the Targets for the Annotations ClassLevelAnnotation.java and MethodLevelAnnotation.java are set to ElementType.TYPE and ElementType.METHOD respectively.
ClassLevelAnnotation.java

[code lang=”java”]package net.javabeat.articles.java6.newfeatures.customannotations;

import java.lang.annotation.*;

@Target(value = {ElementType.TYPE})
public @interface ClassLevelAnnotation {
}
[/code]

MethodLevelAnnotation.java

[code lang=”java”]package net.javabeat.articles.java6.newfeatures.customannotations;

import java.lang.annotation.*;

@Target(value = {ElementType.METHOD})
public @interface MethodLevelAnnotation {
}
[/code]

AnnotatedJavaFile.java

[code lang=”java”]package net.javabeat.articles.java6.newfeatures.customannotations;

@ClassLevelAnnotation()
public class AnnotatedJavaFile {

@MethodLevelAnnotation
public void annotatedMethod(){
}
}[/code]
The above is a Sample Java File that makes use of the Class Level and the Method Level Annotations. Note that @ClassLevelAnnotation is applied at the Class Level and the @MethodLevelAnnotation is applied at the method Level. This is because both the Annotation Types have been defined to be tagged to these respective Elements only with the help of @Target Annotation.

2.3) Writing a Simple Custom Annotation Processor

TestAnnotationProcessor.java

[code lang=”java”]package net.javabeat.articles.java6.newfeatures.customannotations;

import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;

@SupportedAnnotationTypes(value= {"*"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)

public class TestAnnotationProcessor extends AbstractProcessor {

@Override
public boolean process(
Set<?> extends TypeElement> annotations, RoundEnvironment roundEnv){

for (TypeElement element : annotations){
System.out.println(element.getQualifiedName());
}
return true;
}
}[/code]
Let us discuss the core points in writing a Custom Annotation Processor in Java 6. The first notable thing is that Test Annotation Processor class extends AbstractProcessor class which encapsulates an Abstract Annotation Processor. We have to inform what Annotation Types our Test Annotation Processor Supports. This is manifested through the Class-Level Annotation called @SupportedAnnotationTypes(). A value of “*” indicates that all types of Annotations will be processed by this Annotation Processor. Which version of Source Files this Annotation Processor supports is mentioned through @SupportedSourceVersion Annotation.
The javac compiler of Mustang has an option called ‘-processor’ where we can specify the Name of the Annotation Processor along with a Set of Java Source Files containing the Annotations. For example, in our case, the command syntax would be something like the following,

[code lang=”java”]javac -processor
net.javabeat.articles.java6.newfeatures.customannotations.TestAnnotationProcessor
AnnotatedJavaFile.java[/code]

The above command tells that the name of the Annotation Processor is net.javabeat.articles.java6.newfeatures.customannotations.TestAnnotationProcessor and it is going to process the AnnotatedJavaFile.java. As soon as this command is issued in the console, the TestAnnotationProcessor.process() method will be called by passing the Set of Annotations that are found in the Source Files along with the Annotation Processing Information as represented by RoundEnvironment. This TestAnnotationProcessor just list the various Annotations present in the Sample Java File (AnnotatedJavaFile.java) by iterating over it.
Following is the output of the above program

[code lang=”java”]net.javabeat.articles.java6.newfeatures.customannotations.ClassLevelAnnotation
net.javabeat.articles.java6.newfeatures.customannotations.MethodLevelAnnotation[/code]

3) Streaming API for XML

3.1) Introduction

Streaming API for XML, simply called StaX, is an API for reading and writing XML Documents. Why need another XML Parsing API when we already have SAX (Simple API for XML Parsing) and DOM (Document Object Model)? Both SAX and DOM parsers have their own advantages and disadvantages and StaX provides a solution for the disadvantages that are found in both SAX and DOM. It is not that StaX replaces SAX and DOM.
SAX, which provides an Event-Driven XML Processing, follows the Push-Parsing Model. What this model means is that in SAX, Applications will register Listeners in the form of Handlers to the Parser and will get notified through Call-back methods. Here the SAX Parser takes the control over Application thread by Pushing Events to the Application. So SAX is a Push-Parsing model. Whereas StaX is a Pull-Parsing model meaning that Application can take the control over parsing the XML Documents by pulling (taking) the Events from the Parser.
The disadvantage of DOM Parser is, it will keep the whole XML Document Tree in memory and certainly this would be problematic if the size of the Document is large. StaX doesn’t follow this type of model and it also has options for Skipping a Portion of a large Document during Reading.
The core StaX API falls into two categories and they are listed below. They are

  1. Cursor API
  2. Event Iterator API

Applications can any of these two API for parsing XML Documents. Let us see what these APIs’ are in detail in the following sections.

3.2) Cursor API

The Cursor API is used to traverse over the XML Document. Think of a Cursor as some kind of Pointer pointing at the start of the XML Document and then Forwarding the Document upon properly instructed. The working model of this Cursor API is very simple. When given a XML Document and asked to parse, the Parser will start reading the XML Document, and if any of the Nodes (like Start Element, Attribute, Text, End Element) are found it will stop and will give information about the Nodes to the Processing Application if requested. This cursor is a Forward only Cursor, it can never go backwards. Both Reading and Writing operations is possible in this cursor API.

3.3) Sample Application

Let us consider a sample Application which will read data from and to the XML Document with the help of the Cursor API. Following is the sample XML Document. The below XML File contains a list of Events for a person in his/her Calendar.
myCalendar.xml

[code lang=”xml”]<calendar>

<event type = "meeting">
<whom>With my Manager</whom>
<where>At the Conference Hall</where>
<date>June 09 2007</date>
<time>10.30AM</time>
</event>

<event type = "birthday">
<whom>For my Girl Friend</whom>
<date>01 December</date>
</event>

</calendar>[/code]

ReadingUsingCursorApi.java

[code lang=”java”]package net.javabeat.articles.java6.newfeatures.stax;

import java.io.*;
import javax.xml.stream.*;
import javax.xml.stream.events.*;

public class ReadingUsingCurorApi {

private XMLInputFactory inputFactory = null;
private XMLStreamReader xmlReader = null;

public ReadingUsingCurorApi() {
inputFactory = XMLInputFactory.newInstance();
}

public void read() throws Exception{

xmlReader = inputFactory.createXMLStreamReader(
new FileReader(".\\src\\myCalendar.xml"));

while (xmlReader.hasNext()){

Integer eventType = xmlReader.next();
if (eventType.equals(XMLEvent.START_ELEMENT)){
System.out.print(" " + xmlReader.getName() + " ");
}else if (eventType.equals(XMLEvent.CHARACTERS)){
System.out.print(" " + xmlReader.getText() + " ");
}else if (eventType.equals(XMLEvent.ATTRIBUTE)){
System.out.print(" " + xmlReader.getName() + " ");
}else if (eventType.equals(XMLEvent.END_ELEMENT)){
System.out.print(" " + xmlReader.getName() + " ");
}
}
xmlReader.close();
}

public static void main(String args[]){
try{
ReadingUsingCurorApi obj = new ReadingUsingCurorApi();
obj.read();
}catch(Exception exception){
exception.printStackTrace();
}
}
}[/code]
XMLInputFactory is the Factory Class for creating Input Stream objects which is represented by XMLStreamReader. An instance of type XMLStreamReader is created by calling XMLInputFactory.createXMLStreamReader() by passing the XML File to be parsed. At this stage, the Parser is ready to read the XML Contents if a combination call to XMLStreamReader.hasNext() and XMLStreamReader.next() is made. The entire Document is traversed in the while loop and the appropriate node’s value is taken by checking the various Element Types.

3.4) Event Iterator API

The Working Model of this Event Iterator API is no more different from the Cursor API. As the Parser starts traversing over the XML Document and if any of the Nodes are found, it will provide this information to the Application that is processing in the form of XML Events. Applications can loop over the entire Document, by requesting for the Next Event. This Event Iterator API is implemented on top of Cursor API.

3.5) Sample Application

Now let us take over a Sample Application using the Event Iterator API which is parsing on the XML Document myCalendar.xml.
ReadingUsingEventIterator.java

[code lang=”java”]package net.javabeat.articles.java6.newfeatures.stax;

import java.io.*;
import javax.xml.stream.*;
import javax.xml.stream.events.*;

public class ReadingUsingEventIteratorApi {

private XMLInputFactory inputFactory = null;
private XMLEventReader xmlEventReader = null;

public ReadingUsingEventIteratorApi() {
inputFactory = XMLInputFactory.newInstance();
}

public void read() throws Exception{

xmlEventReader = inputFactory.createXMLEventReader(
new FileReader(".\\src\\myCalendar.xml"));

while (xmlEventReader.hasNext()){

XMLEvent xmlEvent = xmlEventReader.nextEvent();
if (xmlEvent.isStartElement()){
System.out.print(" " + xmlEvent.asStartElement().getName() + " ");
}else if (xmlEvent.isCharacters()){
System.out.print(" " + xmlEvent.asCharacters().getData() + " ");
}else if (xmlEvent.isEndElement()){
System.out.print(" " + xmlEvent.asEndElement().getName() + " ");
}
}

xmlEventReader.close();
}

public static void main(String args[]){
try{
ReadingUsingEventIteratorApi obj = new ReadingUsingEventIteratorApi();
obj.read();
}catch(Exception exception){
exception.printStackTrace();
}
}
}[/code]
If XMLStreamReader class represents the Reader for stream reading the XML Contents, then XMLEventReader represents the class for reading the XML Document as XML Events (represented by javax.xml.stream.events.XMLEvent). The rest of the reading logic is the same as that of the ReadingUsingCurorApi.java.

4) Conclusion

This article covered the leftover features of the Part I New features of Java 6. Starting with Pluggable Annotation Processing API, it covered what Annotations are, then guided us how to write Custom Annotations and Custom Annotation Processor. Then it traversed over the Cursor API and the Event Iterator API of StaX such as how to read XML Documents along with well-defined samples. Finally through Java API for XML Binding, it details how to map Java and XML Documents with some sample applications.

Filed Under: Java Tagged With: Java 6.0, JAXB

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved