Schema validation with XSDValidator

In this section, we shall create a schema validation application using the schema validator class oracle.xml.schemavalidator.XSDValidator. The application is created in the XMLSchemaValidator class. Import the oracle.xml.parser.schema package and the oracle.xml.schemavalidator.XSDValidator class.

Creating a schema validator

The XSDValidator class is used to validate an XML document that has been built into a DOM tree. First, we need to create an XSDValidator object:

XSDValidator xsdValidator = new XSDValidator ();

The XML schema with which an XML document is validated is set with the setSchema(XMLSchema) method. An XMLSchema object represents a schema document as a DOM tree. An XSDBuilder object is used to create an XMLSchema object from an XML schema document. Create an XSDBuilder object:

XSDBuilder builder = new XSDBuilder();

Build an XMLSchema object from an InputSource object using the build(InputSource) method. The XSDBuilder class provides the overloaded build methods discussed in the following table:

Create an InputSource object from schema document and invoke the build(InputSource) method of XSDBuilder object. We have used InputSource for the input because most SAX parser implementations convert the input to InputSource, and most parsers are SAX based. It is better to specify the input directly as InputSource rather than have the SAX or JAXP implementation convert the input to InputSource. Set the XMLSchema object returned by the build method on the XSDValidator object created earlier. The procedure to create an XMLSchema object from a schema document, and set the schema on an XSDValidator object is as follows:

InputStream inputStream=new FileInputStream(new File("catalog.xsd"));
InputSource inputSource=new InputSource(inputStream);
XMLSchema schema = builder.build(inputSource);
xsdValidator.setSchema(schema);

Setting the error handler

When validating an XML document errors might get generated. For error handling, create and register an ErrorHandler object with the XSDValidator object. The ErrorHandler interface is the basic error handler for SAX parsing. The SAX standard for reporting errors is the most commonly used error handling model because most XML processing including DOM parsing is based on SAX parsing. The DefaultHandler class implements the ErrorHandler interface. Create a class CustomErrorHandler that extends the DefaultHandler class. In the error handling class CustomErrorHandler, override the error handling methods of class DefaultHandler. Add variable hasValidationError of type boolean and saxParseException of type SAXParseException. An error handling method

gets invoked if a validation error is generated. In the error handling methods set instance variable hasValidationError to true, and saxParseException to the SAXParseException parameter value. The custom error handling class is shown in the following listing:

private class CustomErrorHandler extends DefaultHandler
{
protected boolean hasValidationError = false;
protected SAXParseException saxParseException=null;
public void error(SAXParseException exception)
{
hasValidationError = true;
saxParseException=exception;
}
public void fatalError(SAXParseException exception)
{
hasValidationError = true;
saxParseException=exception;
}
public void warning(SAXParseException exception)
{
}
}

Create a CustomErrorHandler object for error handling. The class that holds an error message including the line number is oracle.xml.parser.v2.XMLError. Create an object of type XMLError and register the CustomErrorHandler with the XMLError object with the setErrorHandler(ErrorHandler) method. Set the XMLError object on the XSDValidator object created earlier with the setError(XMLError) method. The procedure to create and set an ErrorHandler object on an XSDValidator object is shown in the following listing:

CustomErrorHandler errorHandler=new CustomErrorHandler();
XMLError xmlError=new XMLError();
xmlError.setErrorHandler(errorHandler);
xsdValidator.setError(xmlError);

Validating the XML document

The XSDValidator class provides an overloaded validate method to validate an XML document with an XML schema. The XML document input to the validate method may be in the form of an XMLDocument object, an InputStream object, or a URL object. We shall validate with the validate(InputStream) method. Create an InputStream object from the XML document catalog.xml, and validate it with the XML schema document using the validate(InputStream) method of class XSDValidator, as shown in the following listing:

InputStream inputStream=new FileInputStream(new File("catalog.xml"));
xsdValidator.validate(inputStream);

Running the Java application

To run the XMLSchemaValidator.java application, right-click on XMLSchemaValidator.java in Application Navigator and select Run. As catalog.xml does not have any validation errors, the output XML Document validates with XML schema gets generated.

Running the Java application

To demonstrate error handling, add an error in the XML document. As an example, add a title element in a journal element:

<journal>
<title>Oracle Magazine </title>
</journal>

Run the XMLSchemaValidator application again. A validation error gets generated:

XML Document has Validation Error:XML-24534: (Error) Element 'title' not expected.

XMLSchemaValidator.java is listed here with explanations about the different sections of the Java application.

  1. First, we declare the import statements for the different classes that we need.
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import oracle.xml.schemavalidator.XSDValidator;
    import oracle.xml.parser.schema.*;
    import oracle.xml.parser.v2.XMLError;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
    import org.xml.sax.helpers.DefaultHandler;
    import java.io.IOException;
    import java.io.InputStream;
    import org.xml.sax.InputSource;
    
  2. Next, we add the Java class declaration XMLSchemaValidator.
    public class XMLSchemaValidator{
    
  3. Next, we define the method validateXMLDocument to validate an XML document.
    public void validateXMLDocument(InputStream input)
    {
    try {
    
  4. We create an XSDValidator object and set the XML schema on the XSDValidator.
    XSDValidator xsdValidator=new XSDValidator();
    XMLSchema schema =getXMLSchema();
    xsdValidator.setSchema(schema);
    
  5. We create an error handler and set the error handler on the XSDValidator. We validate the XML document and output the validation errors (if any).
    CustomErrorHandler errorHandler=new CustomErrorHandler();
    XMLError xmlError=new XMLError();
    xmlError.setErrorHandler(errorHandler);
    xsdValidator.setError(xmlError);
    xsdValidator.validate(input);
    if(errorHandler.hasValidationError==true)
    System.err.println("XML Document has Validation
    Error:"+errorHandler.saxParseException.getMessage());
    else
    System.out.println("XML Document validates with XML schema");
    }catch(IOException e)
    {
    System.err.println("IOException "+e.getMessage());
    }catch (SAXException e) {
    System.err.println("SAXException "+e.getMessage());
    }catch (XSDException e) {
    System.err.println("XSDException "+e.getMessage());
    }
    }
    
  6. We define the custom error handler inner class CustomErrorHandler, which extends the DefaultHandler class.
    private class CustomErrorHandler extends DefaultHandler
    {
    protected boolean hasValidationError = false;
    protected SAXParseException saxParseException=null;
    public void error(SAXParseException exception)
    {
    hasValidationError = true;
    saxParseException=exception;
    }
    public void fatalError(SAXParseException exception)
    {
    hasValidationError = true;
    saxParseException=exception;
    }
    public void warning(SAXParseException exception)
    {
    }
    }
    
  7. We define the getXMLSchema method to create an XMLSchema object from an XML schema document.
    public XMLSchema getXMLSchema() {
    try {
    XSDBuilder builder = new XSDBuilder();
    InputStream inputStream =
    new FileInputStream(new File("catalog.xsd"));
    InputSource inputSource = new InputSource(inputStream);
    XMLSchema schema = builder.build(inputSource);
    return schema;
    } catch (XSDException e) {
    System.err.println("XSDException " + e.getMessage());
    }catch (FileNotFoundException e) {
    System.err.println("FileNotFoundException " +
    e.getMessage());
    }
    return null;
    }
    
  8. Finally, we add the main method in which we create an instance of the XMLSchemaValidator class and invoke the validateXMLDocument method.
    public static void main(String[] argv) {
    try {
    InputStream inputStream =
    new FileInputStream(new File("catalog.xml"));
    XMLSchemaValidator validator = new
    XMLSchemaValidator();
    validator.validateXMLDocument(inputStream);
    } catch (FileNotFoundException e) {
    System.err.println("FileNotFoundException " +
    e.getMessage());
    }
    }
    }