JAXB Schema Validation

Learn to validate XML against schema (xsd) and then unmarshalling XML to Java object. Also learn to check validation errors during xml schema validation if validation fails.

Read More: How to generate schema from JAXB classes

1. Convert XML to Java Object after XSD Validation

We have already seen the example to read XML file to Java object. Let’s modify that example to now validate the XML against XSD before populating the Employee object.

package com.howtodoinjava.demo;

import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;
import com.howtodoinjava.demo.model.Employee;

public class JaxbExample 
{
	public static void main(String[] args) 
	{
		String xmlFile = "employee.xml";
		String xsdFile = "employee.xsd";
		
		jaxbXmlFileToObject(xmlFile, xsdFile);
	}

	private static void jaxbXmlFileToObject(String xmlFile, String xsdFile) {
		
		JAXBContext jaxbContext;
		
		try 
		{
			//Get JAXBContext
			jaxbContext = JAXBContext.newInstance(Employee.class);
			
			//Create Unmarshaller
			Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
			
			//Setup schema validator
			SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema employeeSchema = sf.newSchema(new File(xsdFile));
			jaxbUnmarshaller.setSchema(employeeSchema);
			
			//Unmarshal xml file 
			Employee employee = (Employee) jaxbUnmarshaller.unmarshal(new File(xmlFile));
			
			System.out.println(employee);
		}
		catch (JAXBException | SAXException e) 
		{
			e.printStackTrace();
		}
	}
}

Program output.

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

Where the content of employee.xml and employee.xsd is given below.

<employees>
	<employee id="101">
		 <name>Lokesh Gupta</name>
	    <title>Author</title>
	</employee>
	<employee id="102">
		 <name>Brian Lara</name>
	    <title>Cricketer</title>
	</employee>
</employees>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="department" type="department"/>

  <xs:element name="employee" type="employee"/>

  <xs:complexType name="employee">
    <xs:sequence>
      <xs:element ref="department" minOccurs="0"/>
      <xs:element name="firstName" type="xs:string" minOccurs="0"/>
      <xs:element name="id" type="xs:int" minOccurs="0"/>
      <xs:element name="lastName" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="department">
    <xs:sequence>
      <xs:element name="id" type="xs:int" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

2. Schema Validation Errors

XSD validation against XML will not be always successful. Many times, you will get validation errors. These errors will be thrown as SAXException. So catch this exception and it will have the context where validation failed.

e.g. I have update the schema file with this change.

<xs:element name="firstName" type="xs:string" minOccurs="0"/>

//to 

<xs:element name="firstName" type="xs:int" minOccurs="0"/>

Now look at validation error.

javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; systemId: file:/C:/Users/lokesh/workspace/App/employee.xml; lineNumber: 7; columnNumber: 34; 
cvc-datatype-valid.1.2.1: 'Lokesh' is not a valid value for 'integer'.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
at com.howtodoinjava.demo.JaxbExample.jaxbXmlFileToObject(JaxbExample.java:45)
at com.howtodoinjava.demo.JaxbExample.main(JaxbExample.java:23)
Caused by: org.xml.sax.SAXParseException; systemId: file:/C:/Users/lokesh/workspace/App/employee.xml; lineNumber: 7; columnNumber: 34; 
cvc-datatype-valid.1.2.1: 'Lokesh' is not a valid value for 'integer'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:458)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3237)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(XMLSchemaValidator.java:3152)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(XMLSchemaValidator.java:3062)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2140)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:859)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(ValidatorHandlerImpl.java:584)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.endElement(ValidatingUnmarshaller.java:91)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:165)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2973)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
... 7 more

Drop me your questions in comments section.

Happy Learning !!

Was this post helpful?

Join 8000+ Awesome Developers, Like YOU!

3 thoughts on “JAXB Schema Validation”

  1. Hi,
    I have tag in my xml file.while unmarshalling it is throwing “SAXException=XML document structures must start and end within the same entity

    notes: this tag getting created while marshalling for null object

    Reply
  2. How to detect other field’s error? If I change not only but other fields too. I will see only one error. How to see every errors?

    Reply

Leave a Comment

About HowToDoInJava

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

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