By default, the Xerces SAX parser is non-validating. This means that even if a document contains a DTD, the parser doesn't check the document contents to make sure that they conform to its rules. Enabling validation requires the use of the XMLReader.setFeature() method. SAX offers this method to provide different sets of features in an extensible way. You invoke the XMLReader.setFeature() method to enable the schema validation behavior.
public void read(String xmlFileName, String xsdSchemaName) throws Exception { String validationFeature = "http://xml.org/sax/features/validation"; String schemaFeature = "http://apache.org/xml/features/validation/schema"; XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); reader.setProperty ("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", xsdSchemaName); reader.setFeature(validationFeature, true); reader.setFeature(schemaFeature, true); reader.setContentHandler(this); reader.setErrorHandler(this); reader.parse(xmlFileName); }
To set a feature on either org.apache.xerces.parsers.SAXParser, you use the method setFeature(String, boolean). To query a feature, you use the SAX getFeature(String) method. You can see the complete listing of features that you can set at http://www.xerces.apache.org/xerces-j/features.html.
Before looking at the complete code, consider the XSD file in Listing 13-4, which is named Products.xsd and is used for validating the Products.xml file.
Listing 13-4: Products.xsd file
![]() |
<?xml version="1.0" encoding="utf-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Products"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="Product"> <xs:complexType> <xs:sequence> <xs:element name="ProductID" type="xs:unsignedByte" /> <xs:element name="Name" type="xs:string" /> <xs:element name="ProductNumber" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
![]() |
Listing 13-5 shows the complete code required to validate the Products.xml file with the Products.xsd file. To catch the events raised by the parser, you override the methods of the ErrorHandler interface such as warning(), error(), fatalError().
Listing 13-5: Validating an XML file with XSD Schema
![]() |
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; import org.xml.sax.*; import org.xml.sax.helpers.*; public class ProductsSchemaValidation extends DefaultHandler { public static void main(String[] args) throws Exception { System.out.println("Start of Products..."); ProductsSchemaValidation readerObj = new ProductsSchemaValidation(); readerObj.read(args[0], args[1]); } public void read(String xmlFileName, String xsdSchemaName) throws Exception { String validationFeature = "http://xml.org/sax/features/validation"; String schemaFeature = "http://apache.org/xml/features/validation/schema"; XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); reader.setProperty ("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", xsdSchemaName); reader.setFeature(validationFeature, true); reader.setFeature(schemaFeature, true); reader.setContentHandler(this); reader.setErrorHandler(this); reader.parse(xmlFileName); } public void startDocument() throws SAXException { System.out.println("Start of the document"); } public void endDocument() throws SAXException { System.out.println("End of the document"); } public void startElement(String uri, String name, String qName, Attributes atts) { if ("".equals(uri)) System.out.println("Start element: " + qName); else System.out.println("Start element: {" + uri + "}" + name); } public void endElement(String uri, String name, String qName) { if ("".equals(uri)) System.out.println("End element: " + qName); else System.out.println("End element: {" + uri + "}" + name); } public void warning(SAXParseException e) throws SAXException { System.out.println("Warning: "); displayErrorInfo(e); } public void error(SAXParseException e) throws SAXException { System.out.println("Error: "); displayErrorInfo(e); } public void fatalError(SAXParseException e) throws SAXException { System.out.println("Fatal error: "); displayErrorInfo(e); } private void displayErrorInfo(SAXParseException e) { System.out.println(" Public ID: " + e.getPublicId()); System.out.println(" System ID: " + e.getSystemId()); System.out.println(" Line number: " + e.getLineNumber()); System.out.println(" Column number: " + e.getColumnNumber()); System.out.println(" Message: " + e.getMessage()); } }
![]() |
If you run the program passing in the Products.xml and Products.xsd as command line arguments, it will work fine, since the XML file is compliant with the XSD file. However, if you change the root element of the Products.xsd file from P roducts to Products1 and rerun the program, you will see the output shown in Figure 13-5.
Figure 13-5
The output shown in Figure 13-5 clearly proves that validation works fine and because of that the validation violation is reported by the parser.