Java – Jaxb 2.0 Schema validation problem

javajaxbjaxb2validationxml

I am working with Jaxb 2.x and was trying to validate XML document with the given XSD using the following tutorial

Tutorial Link

hers is the code i have written

unmarshaller.setSchema(schema);
        SAXSource source = new SAXSource(new InputSource(xmlFileLocation));
        Validator validator = schema.newValidator();
        validator.setErrorHandler(new XMLErrorHandler<Object>());
         try {
                validator.validate(source);
            } catch (SAXException e) {

and my XMLErrorHanlder class have following signature

public class XMLErrorHandler<T> implements ErrorHandler {
public void error(SAXParseException exception) throws SAXException {
        xmlUnmarshaller.setValidationFlag(true);
        log.error(
                "Line:Col[" + exception.getLineNumber()
                + ":" + exception.getColumnNumber()
                + "]:" + exception.getMessage());


        exception.printStackTrace();

    }
                       }

}

code for warning and fatal has been removed
now its validating the XML with XSD but it only showing the first encountered error while i want to get print on colsole all errors and warning on console

i am not sure where i am doing wrong any help in this will be helpful

Edit1
here is the portion of XSD file

<?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="destination" type="Destination"/>

  <xs:complexType name="Destination">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="destinationID" type="xs:string" minOccurs="0"/>
      <xs:element name="shortDescription" type="xs:string" minOccurs="0"/>
      <xs:element name="longDescription" type="xs:string" minOccurs="0"/>
      <xs:element name="stateID" type="xs:string"/>
      <xs:element name="typeCode" type="xs:int"/>
      <xs:element name="countryCode" type="xs:string"/>
      <xs:element name="categories" type="xs:string"/>
      <xs:element name="transport" type="Transport" minOccurs="0" maxOccurs="1"/>
      <xs:element name="cultures" type="Cultures" minOccurs="0"/>
      <xs:element name="events" type="Events" minOccurs="0" maxOccurs="1"/>
      <xs:element name="placesToVisit" type="PlacesToVisit" minOccurs="0" maxOccurs="1"/>
      <xs:element name="contacts" type="Contact" minOccurs="0" maxOccurs="1"/>
      <xs:element name="addresses" type="address" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>

and the XML file is

<destination xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="destination.xsd">
  <name>Palampur</name>
  <destinationID>PLP</destinationID>
  <shortDescription>shortDescription</shortDescription>
  <longDescription>longDescription</longDescription>
  <typeCode>0</typeCode>
  <categories>categories</categories>

what my assumption after doing some R&D is that there is some issue with XSD structure or the generated XML but i am not sure abt it

Best Answer

There are a couple approaches you can leverage to validate your XML document against an XML schema.

javax.xml.validation APIs

The first is to use the javax.xml.validation APIs to validate your document against an XML schema without JAXB.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="destination" type="Destination"/>

  <xs:complexType name="Destination">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="destinationID" type="xs:string" minOccurs="0"/>
      <xs:element name="shortDescription" type="xs:string" minOccurs="0"/>
      <xs:element name="longDescription" type="xs:string" minOccurs="0"/>
      <xs:element name="stateID" type="xs:string"/>
      <xs:element name="typeCode" type="xs:int"/>
      <xs:element name="countryCode" type="xs:string"/>
      <xs:element name="categories" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

and the XML document:

<?xml version="1.0" encoding="UTF-8"?>
<destination xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="destination.xsd">
  <sd></sd>
  <name>Palampur</name>
  <destinationID>PLP</destinationID>
  <shortDescription>shortDescription</shortDescription>
  <longDescription>longDescription</longDescription>
  <typeCode>ZERO</typeCode>
  <categories>categories</categories>
</destination>

with the following demo code:

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.transform.sax.SAXSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class Demo {

    public static void main(String[] args) throws Exception {
        String xmlFileLocation = "src/validate/blog/input.xml";
        SAXSource source = new SAXSource(new InputSource(xmlFileLocation));

        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema(new File("src/validate/blog/customer.xsd"));
        Validator validator = schema.newValidator();
        validator.setErrorHandler(new MyErrorHandler());

        validator.validate(source);
        System.out.println("DONE");
    }

    private static class MyErrorHandler implements ErrorHandler {

        public void error(SAXParseException arg0) throws SAXException {
            System.out.println("ERROR");
            arg0.printStackTrace(System.out);
        }

        public void fatalError(SAXParseException arg0) throws SAXException {
            System.out.println("FATAL ERROR");
            arg0.printStackTrace(System.out);
        }

        public void warning(SAXParseException arg0) throws SAXException {
            System.out.println("WARNING ERROR");
            arg0.printStackTrace(System.out);
        }

    }

}

Will give the following output displaying multiple errors:

ERROR
org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'sd'. One of '{name}' is expected.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(Unknown Source)
    at javax.xml.validation.Validator.validate(Unknown Source)
    at validate.blog.Demo.main(Demo.java:27)
ERROR
org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'ZERO' is not a valid value for 'integer'.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(Unknown Source)
    at javax.xml.validation.Validator.validate(Unknown Source)
    at validate.blog.Demo.main(Demo.java:27)
ERROR
org.xml.sax.SAXParseException: cvc-type.3.1.3: The value 'ZERO' of element 'typeCode' is not valid.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(Unknown Source)
    at javax.xml.validation.Validator.validate(Unknown Source)
    at validate.blog.Demo.main(Demo.java:27)
DONE

JAXB APIs

The second approach is to validate while performing an unmarshal operation with JAXB.

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.InputSource;

public class JaxbDemo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Destination.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();

        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema(new File("src/validate/blog/customer.xsd"));
        unmarshaller.setSchema(schema);
        unmarshaller.setEventHandler(new MyValidationEventHandler());

        String xmlFileLocation = "src/validate/blog/input.xml";
        unmarshaller.unmarshal(new InputSource(xmlFileLocation));

    }

    private static class MyValidationEventHandler implements ValidationEventHandler {

        public boolean handleEvent(ValidationEvent arg0) {
            System.out.println(arg0.getSeverity());
            return true;
        }

    }

}

For More Information:

Related Topic