XML Developer’s Guide

Generate XML Schema from Java class using ‘schemagen’ tool

Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects.

JAXB provides “xjc” tool to convert XML Schema to class representations. In addition, JAXB includes a “schemagen” tool which can essentially perform the inverse of “xjc”, creating an XML Schema from a set of annotated classes.

In this example, we will see how to generate XML schema from Java class using schemagen tool from command line.

What is an XML schema?

XML schema describes the structure of the data elements and their relationships in an XML document. XML schema can be written using Document Type Definition (DTD), XML Schema Language, and RELAX NG. Previous versions of JAXB reference implementation worked with only DTD and the latest versions uses XML Schema Language. The XML Schema language can also be referred as XML Schema Definition (XSD). We can create many XML document from a XML schema. For easy understanding we can say that,
XML schema ⇔ Java class.
With one Java class, we can create many objects similarly with one XML schema we can create many XML documents.

We use the Java Architecture for XML Binding (JAXB) schema generator tool, schemagen, to generate a XML schema from Java source files or class files.

Process JDK Tool
From Java source file -> XML schema schemagen

‘schemagen’ Command Line Options

We are going to generate a XML schema for a XML document shown below.

 Kumar 30000.0 Junior Developer 
Chennai 242 Main Street TN 600001

Create required Java files

We create two Java classes Employee and Address with proper JAXB annotations set as follows.

Employee.java

package com.theopentutorials.jaxb.beans; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "employee") public class Employee < @XmlAttribute private int id; private String name; private double salary; private String designation; private Address address; public int getId() < return id; >public void setId(int id) < this.id = id; >public String getName() < return name; >public void setName(String name) < this.name = name; >public double getSalary() < return salary; >public void setSalary(double salary) < this.salary = salary; >public String getDesignation() < return designation; >public void setDesignation(String designation) < this.designation = designation; >public Address getAddress() < return address; >public void setAddress(Address address) < this.address = address; >>

Address.java

package com.theopentutorials.jaxb.beans; public class Address < private String line1; private String line2; private String city; private String state; private long zipcode; public String getLine1() < return line1; >public void setLine1(String line1) < this.line1 = line1; >public String getLine2() < return line2; >public void setLine2(String line2) < this.line2 = line2; >public String getCity() < return city; >public void setCity(String city) < this.city = city; >public String getState() < return state; >public void setState(String state) < this.state = state; >public long getZipcode() < return zipcode; >public void setZipcode(long zipcode) < this.zipcode = zipcode; >>

‘schemagen’ command for schema genearation

In Windows open Command Prompt (Windows button + R and type cmd) or Terminal in Linux and go to the folder (use cd command) where your java code exists.

Читайте также:  Java lang reflect jar

    Compile the above Java classes and place the classes in ‘bin’ folder. Type the following command,

C:\Users\iByteCode\Desktop\JAXBCodes\JAXBSchemaGen>javac -d bin src\com\theopentutorials\jaxb\beans\*.java

C:\Users\iByteCode\Desktop\JAXBCodes\JAXBSchemaGen>schemagen -cp bin src\com\theopentutorials\jaxb\beans\Employee.java

Источник

Using JAXB to generate XML from XSD

This is a post originally published by Mohamed Sanaulla from Experiences Unlimited, our latest JCG partner. Mohamed explains how to use JAXB to generate XML from a given XSD. (NOTE: The original post has been slightly edited to improve readability) We can use JAXB to marshal the Java objects into XML using the given Schema and vice versa- unmarshal XML into Java objects. The XML schema can be specified in DTD, XSD or other format. The tool “xjc” can be used to generate the annotated Java classes from the XSD schema. One can download the Java Web Services Developer Pack (WSDP), it includes the JAXB implementation tools required. Here I will throw light on how to generate XML dynamically. The sample XSD being used is: – expense.xsd

Now we use the xjc tool to generate the corresponding Java classes. The generated Java classes are annotated appropriately. I am not going into details about the annotation of the classes, cause it would make things complicated.

xjc.exe expense.xsd By default the command generates the Java classes in a directory named “generated”. There are lot of options which can be used with xjc and one can have a look at using xjc -help The below Main class uses the generated classes for creating the XML. – Main.java

package generated; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import java.math.BigDecimal; public class Main < public static void main(String[] args) throws JAXBException < ObjectFactory factory = new ObjectFactory(); UserT user = factory.createUserT(); user.setUserName("Sanaulla"); ItemT item = factory.createItemT(); item.setItemName("Seagate External HDD"); item.setPurchasedOn("August 24, 2010"); item.setAmount(new BigDecimal("6776.5")); ItemListT itemList = factory.createItemListT(); itemList.getItem().add(item); ExpenseT expense = factory.createExpenseT(); expense.setUser(user); expense.setItems(itemList); JAXBContext context = JAXBContext.newInstance("generated"); JAXBElementelement = factory.createExpenseReport(expense); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE); marshaller.marshal(element,System.out); > >
  • jaxb.encoding
  • jaxb.formatted.output
  • jaxb.schemaLocation
  • jaxb.noNamespaceSchemaLocation
  • jaxb.fragment

The generated XML is shown below:

   Sanaulla   Seagate External HDD August 24, 2010 6776.5    

Источник

Using JAXB for Java to XML Conversion

Do you know how easy it is to convert java objects to and from XML using JAXB?

“Failure is the condiment that gives success its flavor.” ― Truman Capote

1. Introduction

JAXB (Java Architecture for XML Binding) offers a very easy path to integrate XML into your java application. Using JAXB you can easily serialize java objects as XML, and also load java objects from XML. Let us investigate JAXB for this purpose.

In this article, we implement java bean classes for catalog and book. We have already covered how to use DOM and SAX to process XML with the same example. Now let us see how to use JAXB to do the same.

  Gambardella, Matthew  Computer 44.95 2000-10-01 An in-depth look at creating applications with XML.  Ralls, Kim  .

2. Java Object Model

JAXB uses annotations to control aspects of how the XML is serialized and deserialized. As such, you may need to annotate your classes with the appropriate JAXB annotations to get the exact representation you need.

2.1 Catalog

The java object model for our application consists of two classes: Catalog and Book. Here is the Catalog class annotated with the appropriate JAXB annotations.

package sample; import java.util.List; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlElement; @XmlAccessorType(XmlAccessType.FIELD) public class Catalog < @XmlElement(name = "book") private Listbooks; public List getBooks() < return books; >public void setBooks(List books) < this.books = books; >>

The @XmlAccessorType annotation is required when used with @XmlElement to avoid the following exception:

Class has two properties of the same name "books" this problem is related to the following location: at public java.util.List sample.Catalog.getBooks() at sample.Catalog this problem is related to the following location: at private java.util.List sample.Catalog.books at sample.Catalog

It tells JAXB to use the field books (with the name book) for (de-)serialization, rather than the property returned by getBooks().

2.2 Book

And here is the class Book referenced by Catalog. Again we use the @XmlAccessorType annotation along with the @XmlAttribute annotation since we want id to be serialized as an XML attribute rather than an element.

Читайте также:  Html код социальных кнопок

Just for illustration, we have also changed the publish_date in XML to pubdate in java. To properly convert between the two, we need the @XmlElement annotation as shown.

package sample; import java.math.BigDecimal; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; @XmlAccessorType(XmlAccessType.FIELD) public class Book < @XmlAttribute private String id; private String author; private String title; private String genre; private BigDecimal price; @XmlElement(name = "publish_date") private String pubdate; private String description; public String getId() < return id; >public void setId(String id) < this.id = id; >public String getAuthor() < return author; >public void setAuthor(String author) < this.author = author; >public String getTitle() < return title; >public void setTitle(String title) < this.title = title; >public String getGenre() < return genre; >public void setGenre(String genre) < this.genre = genre; >public BigDecimal getPrice() < return price; >public void setPrice(BigDecimal price) < this.price = price; >public String getPubdate() < return pubdate; >public void setPubdate(String pubdate) < this.pubdate = pubdate; >public String getDescription() < return description; >public void setDescription(String description) < this.description = description; >>

3. Reading and Writing XML

Let us now look at the code required to load XML and create objects from the data. It is as simple as:

String xmlFile = . ; Catalog catalog = JAXB.unmarshal(new File(xmlFile), Catalog.class);

Writing XML is similarly very simple. To write to STDOUT:

JAXB.marshal(catalog, System.out);

Write to an output file directly using:

JAXB.marshal(catalog, new File("output.xml"));

4. Generate XML from Java Objects

To create XML from java objects is pretty straighforward too. In the following code, we create the entire data model in memory and serialize it to an XML file.

Catalog catalog = new Catalog(); < Book book = new Book(); book.setId("bk101"); book.setTitle("Pride and Prejudice"); book.setAuthor("Jane Austen"); book.setGenre("Romance"); book.setPrice(new BigDecimal("6.99")); book.setPubdate("2010-04-01"); book.setDescription("\"It is a truth universally acknowledged, that a single man in possession of a good fortune must be in want of a wife.\" So begins Pride and Prejudice, Jane Austen's witty comedy of manners-one of the most popular novels of all time-that features splendidly civilized sparring between the proud Mr. Darcy and the prejudiced Elizabeth Bennet as they play out their spirited courtship in a series of eighteenth-century drawing-room intrigues."); catalog.getBooks().add(book); > < Book book = new Book(); book.setId("bk102"); book.setTitle("To Kill a Mockingbird"); book.setAuthor("Harper Lee"); book.setGenre("Drama"); book.setPrice(new BigDecimal("6.39")); book.setPubdate("2005-07-05"); book.setDescription("One of the best-loved stories of all time, To Kill a Mockingbird has been translated into more than forty languages, sold more than forty million copies worldwide, served as the basis for an enormously popular motion picture, and was voted one of the best novels of the twentieth century by librarians across the country. A gripping, heart-wrenching, and wholly remarkable tale of coming-of-age in a South poisoned by virulent prejudice, it views a world of great beauty and savage inequities through the eyes of a young girl, as her father-a crusading local lawyer-risks everything to defend a black man unjustly accused of a terrible crime."); catalog.getBooks().add(book); >JAXB.marshal(catalog, new File(xmlFile));

5. Using an XmlAdapter for Data Conversion

In the above data model, the publish_date is represented as a String. It should properly be represented as a LocalDate. Let us change the representation and find out what happens.

Читайте также:  Python разница дат в днях

The Book class is modified as follows:

import java.time.LocalDate; . @XmlAccessorType(XmlAccessType.FIELD) public class Book < . @XmlElement(name = "publish_date") private LocalDate pubdate; . public LocalDate getPubdate() < return pubdate; >public void setPubdate(LocalDate pubdate) < this.pubdate = pubdate; >. >

On trying to load the XML as before, we get the following exception.

INFO: No default constructor found on class java.time.LocalDate java.lang.NoSuchMethodException: java.time.LocalDate.() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.getDeclaredConstructor(Class.java:2178) at com.sun.xml.internal.bind.v2.ClassFactory.create0(ClassFactory.java:89) at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:270) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:684 )

This error occurs because 1) there is no default contructor on LocalDate 2) the unmarhsaller does not know how to convert a String to LocalDate.

Both of these problems can be addressed by adding an XmlAdapter. This adapter takes care of converting the required type to and from String. Here is the adapter for converting LocalDate.

package sample; import java.time.LocalDate; import javax.xml.bind.annotation.adapters.XmlAdapter; public class LocalDateAdapter extends XmlAdapter  < @Override public String marshal(LocalDate date) < if ( date == null ) return null; return date.toString(); >@Override public LocalDate unmarshal(String string) < return LocalDate.parse(string); >>

Once the adapter class is created, we need to tell JAXB to use this adapter for conversion. This is done using the @XmlJavaTypeAdapter annotation in the Book class as follows:

. @XmlAccessorType(XmlAccessType.FIELD) public class Book

With this change, the date field is stored as LocalDate and we get no more exceptions from XML (de-)serialization.

6. Modifying XML Using Java 8 Streams

We will now investigate how to use java 8 streams to update XML. As a first step, let us load our sample XML using the java object model and find those books which cost more than, say $30.

BigDecimal cutoff = new BigDecimal("30.0"); catalog .getBooks() .stream() .filter(book -> book.getPrice().compareTo(cutoff) > 0) .forEach(book -> JAXB.marshal( book, System.out));

The output from the above code prints out book elements which satisfy the condition.

 Gambardella, Matthew  Computer 44.95 2000-10-01 An in-depth look at creating applications with XML.  O'Brien, Tim  Computer 36.95 .

Let us now apply a 10% discount to those titles which cost more than $30. This is done with the following code:

BigDecimal cutoff = new BigDecimal("30.0"); BigDecimal newPrice = new BigDecimal("0.90"); catalog .getBooks() .stream() .filter(book -> book.getPrice().compareTo(cutoff) > 0) .forEach(book -> book.setPrice(book.getPrice().multiply(newPrice))); JAXB.marshal(catalog, System.out);

Each book entry is modified so that the new price is 90% of the original. The output from this code reflects the prices.

  Gambardella, Matthew  Computer 40.4550 2000-10-01 An in-depth look at creating applications with XML.  Ralls, Kim  Fantasy 5.95 2000-12-16 .

Note that books which cost below $30 are unchanged from the original.

Conclusion

We have now learnt the basics of using JAXB to convert between java and XML. We create a java model of objects and use annotations to control the XML output. With this arrangement, it is easy to integrate XML into your java application.

Источник

Оцените статью