An XML schema document defines the structure, content, and semantics for XML documents. We know the procedure to create an XML schema in JDeveloper and an XML document instance that conforms to the schema. But if you receive XML documents from another party, the validity of the documents has to be ascertained before the documents may be read and processed. This article by Deepak Vohra is about—validating an XML document with an XML schema. An instance document may be processed against a schema to verify whether the XML document conforms to the rules specified in the schema, a process called schema validation.
JDeveloper built-in schema validation
Oracle JDeveloper 11g has built-in support for XML schema validation. If an XML document includes a reference to an XML schema, the XML document may be validated with the XML schema using the built-in feature. An XML schema may be specified in an XML document using the xsi:noNamespaceSchemaLocation attribute or the xsi:namespaceSchemaLocation attribute. Before we discuss when to use which attribute, we need to define the target namespace. A schema is a collection of type definitions and element declarations whose names belong to a particular namespace called a target namespace. Thus, a target namespace distinguishes between type definitions and element declarations from different collections. An XML schema doesn't need to have a target namespace. If the XML schema has a target namespace, specify the schema's location in an XML document using the xsi:namespaceSchemaLocation attribute. If the XML schema does not have a target namespace, specify the schema location using the xsi:noNamespaceSchemaLocation attribute. The xsi:noNamespaceSchemaLocation and xsi:namespaceSchemaLocation attributes are a hint to the processor about the location of an XML schema document. The example XML schema document that we shall create is catalog.xsd and is listed here:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="catalog"type="catalogType"/>
<xsd:complexType name="catalogType">
<xsd:sequence>
<xsd:element ref="journal" minOccurs="0"maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="journal" type="journalType"/>
<xsd:complexType name="journalType">
<xsd:sequence>
<xsd:element ref="article" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="title" type="xsd:string"/>
<xsd:attribute name="publisher" type="xsd:string"/>
<xsd:attribute name="edition" type="xsd:string"/>
</xsd:complexType>
<xsd:element name="article" type="articleType"/>
<xsd:complexType name="articleType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="section" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
The XML document instance that we shall generate from the schema is catalog.xml and is listed as follows:
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<journal title="Oracle Magazine" publisher="Oracle
Publishing" edition="September-October 2008">
<article section="Features">
<title>Share 2.0</title>
<author>Alan Joch</author>
</article>
</journal>
<journal title="Oracle Magazine" publisher="Oracle
Publishing" edition="March-April 2008">
<article section="Oracle Developer">
<title>Declarative Data Filtering</title>
<author>Steve Muench</author>
</article>
</journal></catalog>
Specify the XML schema location in the XML document using the following attribute declaration:
xsi:noNamespaceSchemaLocation="catalog.xsd"
The XML schema may be in any directory. The example XML document does not include any namespace elements. Therefore, the schema is specified with the xsi:noNamespaceSchemaLocation attribute in the root element catalog. The XML schema may be specified with a relative URL, or a file, or an HTTP URL. The xsi:noNamespaceSchemaLocation attribute we added specifies the relative path to the XML schema document catalog.xsd. To validate the XML document with the XML schema, right-click on the XML document and select Validate XML
.
The XML document gets validated with the XML schema and the output indicates that the XML document does not have any validation errors.
To demonstrate validation errors, add a non-valid element to the XML document. As an example, add the following element to the catalog element after the first journal element:
<article></article>
To validate the modified XML document, right-click on the XML document and select Validate XML. The output indicates validation errors. All the elements after the non-valid element become non-valid. For example, the journal element is valid as a subelement of the catalog element, but because the second journal element is after the non-valid article element, the journal element also becomes non-valid as indicated in the validation output.
XDK 11g also provides a schema validation-specific API known as XSDValidator to validate an XML document with an XML schema. The choice of validation method depends on the additional functionality required in the validation application. XSDValidator is suitable for validation if all that is required is schema validation.
Setting the environment
Create an application (SchemaValidation, for example) and a project (SchemaValidation, for example) in JDeveloper. To create an application and a project select File | New. In the New Gallery window, select Categories | General and Items | Generic Application. Click on OK. In the Create Generic Application window, specify an Application Name and click on Next. In the Name your Generic project window, specify a Project Name and click on Finish. An application and a project get created. Next, add some XDK 11g JAR files to the project classpath. Select the project node in Application Navigator, and select Tools | Project Properties. In the Project Properties window, select Libraries and Classpath. Click on the Add Library button to add a library. In the Add Library window, select the Oracle XML Parser v2 library and click on the OK button. The Oracle XML Parser v2 library gets added to the project Libraries. Select the Add JAR/Directory button to add JAR file xml.jar from the C:OracleMiddlewarejdevelopermodulesoracle.xdk_11.1.1 directory.
First, create an XML document and an XML schema in JDeveloper. To create an XML document, select File | New. In the New Gallery window select Categories | General | XML. In the Items listed select XML Document, and click on the OK button.
In the Create XML File wizard, specify the XML file name, catalog.xml, and click on the OK button. An XML document gets added to the SchemaValidation project in Application Navigator. To add an XML schema, select File | New, and General | XML in the New Gallery window. Select XML schema in the Items listed. Click on the OK button.
An XML schema document gets added to SchemaValidation project.
The example XML document, catalog.xml, consists of a journal catalog. Copy the XML document to the catalog.xml file in the JDeveloper project.
The example XML document does not specify the location of the XML schema document to which the XML document must conform to, because we will be setting the XML schema document in the schema validation application. If the XML schema document is specified in the XML document and the schema validation application, the schema document set in the schema validation application is used.
Next, copy the example XML schema document, catalog.xsd to catalog.xsd in the JDeveloper project Schema Validation.
Each XML schema is required to be in the XML schema namespace http://www.w3.org/2001/XMLSchema. The XML schema namespace is specified with a namespace declaration in the root element, schema, of the XML schema. A namespace declaration is of the format xmlns:xs= <namespace URL> . Though any prefix may be used, xs or xsd is commonly used as shown here:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
Next, we will create Java classes for schema validation. Select File | New and subsequently Categories | General and Items | Java Class in the New Gallery window to create a Java class for schema validation. Click on the OK button. In the Create Java Class window specify a Class Name, XMLSchemaValidator, and a package name, schemavalidation, and click on the OK button. A Java class gets added to the SchemaValidation project. Similarly, add Java classes, DOMValidator and SAXValidator. The schema validation applications are shown in the Application Navigator.
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:
Method |
Description |
build(InputSource source) |
Builds an XMLSchema object from an InputSource object. The InputSource class represents a single input source for an XML entity. |
build(java.io.InputStream in, java.net.URL baseurl) |
Builds an XMLSchema object from an InputStream. The baseurl is used to resolve any relative references to external schemas included with import/include. |
build(java.io.Reader r,java.net.URL baseurl) |
Builds an XMLSchema object from a Reader. The baseurl is used to resolve any relative references. |
build(java.lang.String systemId) |
Builds an XMLSchema object from an XML schema document represented with a systemId. A systemId is a URI. |
build(java.lang.String ns,java.lang.String systemId) |
Builds an XMLSchema object from a XML schema document represented with a String systemId. The ns parameter specifies the schema target namespace and is used to validate the targetNamespace specified in the XML schema document. |
build(java.lang.String ns,java.net.URL systemId) |
Builds an XMLSchema object from an XML schema document represented with a systemIdspecified as a URL. The ns parameter specifies the schema target namespace to validate targetNamespace. |
build(java.net.URL schemaurl) |
Builds an XMLSchema object from a XML schema document represented as a URL object. |
build(XMLDocument[] schemaDoc,java.net.URL baseurl) |
Builds an XMLSchema object from an array of XML schema documents. The baseurl parameter specifies the base URL to be used for any import/include in the schemas. |
build(XMLDocument schemaDoc,java.net.URL baseurl) |
Builds an XMLSchema object from an XML schema document specified as XMLDocument object and a base URL for any import/include in the schema. |
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 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.
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.
- 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; - Next, we add the Java class declaration XMLSchemaValidator.
public class XMLSchemaValidator{
- Next, we define the method validateXMLDocument to validate an
XML document.
public void validateXMLDocument(InputStream input)
{
try { - We create an XSDValidator object and set the XML schema on
the XSDValidator.
XSDValidator xsdValidator=new XSDValidator();
XMLSchema schema =getXMLSchema();
xsdValidator.setSchema(schema); - 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());
}
} - 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)
{
}
} - 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;
} - 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());
}
}
}
Summary
An XML schema defines the structure of an XML document. In this article we discussed validating an XML document with an XML schema using XSDValidator. JDeveloper 11g provides built-in support for validating an XML document with an XML schema. JDeveloper also includes the XDK 11g through which an XML document may be validated with an XML schema in a Java application.
If you have read this article you may be interested to view :
- XPath Support in Oracle JDeveloper - XDK 11g
- Schema Validation using SAX and DOM parser with Oracle JDeveloper - XDK 11g
About the Author :
Deepak Vohra
Deepak Vohra is a consultant and a principal member of the NuBean software company. Deepak is a Sun certified Java Programmer and a Web Component Developer, and has worked in the fields of XML and Java programming and J2EE for over five years. Deepak is the author of Packt's JDBC 4.0 and Oracle JDeveloper for J2EE Development book.
Books From Packt
|
Post new comment