Generate Namespace & Schema Information using JAXB Marshalling

XML Namespace is used to avoid xml element name conflicts. Since XML elements are defined by developers, they tend to give any suitable name to an element. Thus we might find conflicts when we try to merge XML documents from two different sources. In such situations XML namespace is used to avoid conflicts.

In this article we will discuss how to generate namespaces for xml elements when marshalling objects to xml.


XML Document

Shown below is the xml document that we would generate using JAXB:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:mvc="http://www.springframework.org/schema/mvc
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.springframework.org/schema/mvc 
       http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
       <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
    
       <context:component-scan base-package="examples"/>
    
       <mvc:resources mapping="/resources/**" location="/resources/"/>
</beans>

It is a Spring configuration XML document. It is a perfect candidate for our example as there are multiple namespaces available in the document.

The beans and bean element belongs to the default namespace, ‘http://www.springframework.org/schema/beans’, hence they doesn’t uses a prefix. 

The component-scan element belongs to ‘http://www.springframework.org/schema/context’ namespace and the resources element belongs to the ‘http://www.springframework.org/schema/mvc’ namespace.


Package Level Annotation

We need to use package level annotations to define namespace information. Package level annotations are required to be declared in a special file called as package-info.java.

JAXB provides the @XMLSchema annotation, which we can use to generate namespace information as shown below:

@javax.xml.bind.annotation.XmlSchema(namespace="http://www.springframework.org/schema/beans" ,
    elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
    xmlns={
	@javax.xml.bind.annotation.XmlNs(namespaceURI="http://www.springframework.org/schema/beans", prefix=""),
	@javax.xml.bind.annotation.XmlNs(namespaceURI="http://www.springframework.org/schema/context", 
prefix="context"), @javax.xml.bind.annotation.XmlNs(namespaceURI="http://www.springframework.org/schema/mvc", prefix="mvc") } ) package cubearticle.examples.jaxb;

The 'namespace' attribute defines the default namespace of our XML document. We use the 'elementFormDefault' attribute to specify that all the elements in this document must be qualified by a prefix which we defined in 'xmlns' attribute.

Notice that we use a blank prefix for our default namespace, this is necessary to avoid generating a implementation specific prefix for the default namespace.


Create package-info.java with Eclipse

We cannot create a package-info.java file with eclipse using 'New --> Class' option, since the filename will not be valid. But we have an option of creating it with 'New --> Package', by checking the 'Create package-info.java' checkbox. See the below image:

package-info.java in eclipse

Defining the POJOs

Before we start with the marshalling of Java objects to XML document we need to define the POJO classes that will represent the XML documnet. Shown below are the POJO classes:

Beans.java

@XmlRootElement
public class Beans {	
    private Bean bean;
    private Resources resources;
    private ComponentScan componentScan;
	
    @XmlElement
    public Bean getBean() {
	return bean;
    }
    public void setBean(Bean bean) {
	this.bean = bean;
    }
	
    @XmlElement(namespace="http://www.springframework.org/schema/mvc")
    public Resources getResources() {
	return resources;
    }
    public void setResources(Resources resources) {
	this.resources = resources;
    }
	
    @XmlElement(name="component-scan", namespace="http://www.springframework.org/schema/context")
    public ComponentScan getComponentScan() {
	return componentScan;
    }
    public void setComponentScan(ComponentScan componentScan) {
	this.componentScan = componentScan;
    }
}

While performing unmarshalling, JAXB needs to know which namespace each element belongs to. This is important to generate proper prefix for the elements. Hence we used the 'namespace' attribute in the @XMLElement annotation to inform JAXB about the namespace of the particular element.

All other POJOs are quite simple.

Bean.java

@XmlType(propOrder={"id", "className"})    // Defines the order in which the attributes appear
public class Bean {	
    private String id;
    private String className;
	
    @XmlAttribute
    public String getId() {
 	return id;
    }
    public void setId(String id) {
	this.id = id;
    }
	
    @XmlAttribute(name="class")
    public String getClassName() {
 	return className;
    }
    public void setClassName(String className) {
	this.className = className;
    }	
}

ComponentScan.java

public class ComponentScan {

    private String basePackage;

    @XmlAttribute(name="base-package")
    public String getBasePackage() {
	return basePackage;
    }

    public void setBasePackage(String basePackage) {
	this.basePackage = basePackage;
    }
}

Resources.java

@XmlType(propOrder={"mapping", "location"})	
public class Resources {
    private String mapping;
    private String location;
	
    @XmlAttribute
    public String getMapping() {
	return mapping;
    }
	
    public void setMapping(String mapping) {
	this.mapping = mapping;
    }
	
    @XmlAttribute
    public String getLocation() {
	return location;
    }
	
    public void setLocation(String location) {
	this.location = location;
    }	
}

Generating Schema Location

We can generate the schema location attributes in the XML document while marshalling, by setting the schema location property of the JAXB marshaller. Shown below is our Main class where we use the schema location property of the JAXB marshaller.

public class Main {
    
    public static void main(String[] args)  throws JAXBException{
        File xml = new File("config.xml");
Beans beans = new Beans(); Bean bean = new Bean(); bean.setId("viewResolver"); bean.setClassName("org.springframework.web.servlet.view.InternalResourceViewResolver"); Resources resources = new Resources(); resources.setMapping("/resources/**"); resources.setLocation("/resources/"); ComponentScan componentScan = new ComponentScan(); componentScan.setBasePackage("examples"); beans.setBean(bean); beans.setResources(resources); beans.setComponentScan(componentScan); JAXBContext contx = JAXBContext.newInstance(Beans.class); Marshaller marshaller = contx.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.springframework.org/schema/mvc " + "http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd " + "http://www.springframework.org/schema/beans " + "http://www.springframework.org/schema/beans/spring-beans.xsd " + "http://www.springframework.org/schema/context " + "http://www.springframework.org/schema/context/spring-context-4.0.xsd"); marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true ); //Pretty Print the xml marshaller.marshal(beans, xml); } }

Download Source Code

You can download the source code of the example discussed in this article.

RELATED ARTICLES

Handling Complex Types with JAXB Adapters

JAXB provides a convenient way to map complex data types to xml representations. JAXB provides XMLJavaAdapter to handle such custom marshalling and unmarshalling needs.

View Article

Object-XML Binding using JAXB

JAXB is a Java API that simplifies the access of XML documents within a Java Application. This articles demonstrates xml to object conversion and vice-versa using JAXB.

View Article

XML Schema Validation with JAXB

XML documents are often required to be validated against a schema, which contains some rules that the xml elements must respect. JAXB can be used to simplify this process of xml schema validation.

View Article