JAXB Schema Validation

Lokesh Gupta

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 jakarta.xml.XMLConstants;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.validation.Schema;
import jakarta.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 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.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode