[Solved] JAXB UnmarshalException: unexpected element

We will often need to unmarshal Java objects that do not have JAXB annotations, and we are not permitted to make any changes in the source code. This situation may occur when we are working with legacy code or some client jar for which we do not have source code.

1. Problem when unmarshaling without JAXB annotations

In such a case, if we try to unmarshal Java object to XML directly, then we will get an error like this.

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"employee"). Expected elements are (none)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)

Where Employee.java class is as below. It does not have any JAXB annotation such as @XmlRootElement.

public class Employee implements Serializable {

	private static final long serialVersionUID = 1L;

	private Integer id;
	private String firstName;
	private String lastName;
	private Department department;

	//constructors, getters and setters

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department="
				+ department + "]";
	}
}

2. Solution to Unmarshal without JAXB annotations

In absence of @XmlRootElement annotation, JAXB is not able to build JAXBElement instance for Employee object. So that’s where you have to help JAXB to construct it manually.

/**
  * Unmarshal XML data from the specified XML Source by <tt>declaredType</tt> and return the
  * resulting content tree.
  * @param  source       source the XML Source to unmarshal XML data from (providers are
  *               only required to support SAXSource, DOMSource, and StreamSource)
  *
  * @param  declaredType  appropriate JAXB mapped class to hold <tt>source</tt>'s xml root element
  * 
  * @return value        Java content rooted by JAXB Element
  */
public <T> JAXBElement<T> unmarshal( javax.xml.transform.Source source, Class<T> declaredType )
        throws JAXBException;

For example –

JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller
          .unmarshal(new StreamSource(xmlFile), Employee.class);

3. Demo

Now let’s see how this unmarshalling code works.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
    <department>
        <id>101</id>
        <name>IT</name>
    </department>
    <firstName>Lokesh</firstName>
    <id>1</id>
    <lastName>Gupta</lastName>
</employee>
import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
 
import com.howtodoinjava.demo.model.Employee;
 
public class JaxbExample 
{
  public static void main(String[] args) 
  {
    String fileName = "employee.xml";
 
    jaxbXmlFileToObject(fileName);
  }
 
  private static void jaxbXmlFileToObject(String fileName) 
  {
    File xmlFile = new File(fileName);
    JAXBContext jaxbContext;
    try
    {
      jaxbContext = JAXBContext.newInstance(Employee.class);
      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
       
      JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller
          .unmarshal(new StreamSource(xmlFile), Employee.class);
       
      Employee employee = jaxbElement.getValue();
       
      System.out.println(employee);
    }
    catch (JAXBException e) 
    {
      e.printStackTrace();
    }
  }
}

Program Output:

Employee [id=1, firstName=Lokesh, lastName=Gupta, department=Department [id=101, name=IT]]

Drop me your questions in the comments section.

Happy Learning !!

Comments

Subscribe
Notify of
guest
3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.