Friday, June 15, 2012

Unmarshalling XML files with jaxb

In this post I am going to explain how to create a schema definition from a sample xml file and use that schema definition file to marshalling and un-marshalling by using jaxb2.

Following is the sample xml formal I want to handle. (Suppose we have a web service and it can accept this kind of requests)

    
        Eshan
        test@gmail.com
    
    
        
            SE-12
            web camera
        
        
            SE-75
            mobile phone
        
    

You can create the schema definition file (xsd) of a given  sample by using modern IDE's. For this purpose I used Intelij xml to xsd converter which makes life easier. But we need to edit the generated xsd file for our simplicity. So following is the schema definition for the above xml file.

    

    
        

            
                
                    
                
            

            
                
                    
                    
                
            

        
    

    
        
            
            
        
    

    
        
            
        
    

    
        
            
            
        
    


Now we have finished the work with schema related stuff. Then we need to generate generate java classes from this xsd file. So its time to deal with jaxb2. In this case I had a problem which is the generated java classes are not in a proper naming convention. (All tha classes has "Type" postfix). To fix that we can use a bindings xml which can be pass as a parameter to jaxb.

    
        
            
        

        
            
        
        
            
        
        
            
        
        
            
        
        

So now we are almost done. Its time to generate java classes from these two xml files (xsd file and binding xml). For this purpose instead of calling jaxb xjc directly, I used maven jaxb plugin which is more flexible. following is the jaxb plugin confutation which comes in your pom file.
 
        
            
                generated-sources/xjc/com/demo/xsd
            
        
        
            
                org.jvnet.jaxb2.maven2
                maven-jaxb2-plugin
                
                    
                        
                            generate
                        
                    
                
                
                    src/main/resources
                    true
                    true
                    false
                    true
                    
                        bindings.xml
                    
                
            
        
    
Once you invoke the maven target it will create the java classes of the complex types in our schema definition file. SO now its time to write a client program which uses those java classes to unmarshall a sample xml file.
package com.demo.xsd;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import java.io.File;

public class Unmarshalling {
    public static void main(String[] args) {

        try {                 
            //sample xml file to be unmarshall
            File file = new File("path/to/sample.xml");
            javax.xml.bind.JAXBContext jc = javax.xml.bind.JAXBContext
                    .newInstance(Order.class);
            javax.xml.bind.Unmarshaller u = jc.createUnmarshaller();
            JAXBElement orderJAXBElement = u.unmarshal(new StreamSource(file),
            Order.class);
            Order order1 = orderJAXBElement.getValue();
            String itemName =order1.getItems().item.get(0).getName();
            System.out.println("Item name " + itemName );

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

So we are done. One important thing to mention is with the jaxb 2 xml validation part is being lost(for ans example lets say we need to restrict a particular element to have only specific string values, then the unmarshalling process should throw and parsing exception)

 But in case of you need to validate xml you can do it by setting the schema file to the unmarshaller object as follows.
SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);  

     jaxbUnmarshaller.setSchema(sf.newSchema(new File("/path/sample.xsd")));

1 comment: