XSD Tutorials - Herong's Tutorial Examples - v5.23, by Herong Yang
Validating XML Documents with Schema Locations
This section describes a tutorial example on how to validate an XML document with schema location assigned inside the XML document using Xerces API.
Providing the schema location directly to the XML Schema processor to validate XML documents in Java is easy with the latest JDK package. Here is a sample program, XsdSchemaValidator.java, used in previous tutorials that loads an XML Schema document to validate any a given XML document:
/* XsdSchemaValidator.java - Copyright (c) 2002-2013 HerongYang.com. All Rights Reserved. */ import javax.xml.validation.SchemaFactory; import javax.xml.validation.Schema; import javax.xml.XMLConstants; import javax.xml.transform.sax.SAXSource; import org.xml.sax.InputSource; import javax.xml.validation.Validator; import java.io.*; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.ErrorHandler; class XsdSchemaValidator { private static int errorCount = 0; public static void main(String[] a) { if (a.length<2) { System.out.println("Usage:"); System.out.println("java XsdSchemaValidator schema_file_name " + "xml_file_name"); } else { String schemaName = a[0]; String xmlName = a[1]; Schema schema = loadSchema(schemaName); validateXml(schema, xmlName); } } public static void validateXml(Schema schema, String xmlName) { try { // creating a Validator instance Validator validator = schema.newValidator(); // setting my own error handler validator.setErrorHandler(new MyErrorHandler()); // preparing the XML file as a SAX source SAXSource source = new SAXSource( new InputSource(new java.io.FileInputStream(xmlName))); // validating the SAX source against the schema validator.validate(source); System.out.println(); if (errorCount>0) { System.out.println("Failed with errors: "+errorCount); } else { System.out.println("Passed."); } } catch (Exception e) { // catching all validation exceptions System.out.println(); System.out.println(e.toString()); } } public static Schema loadSchema(String name) { Schema schema = null; try { String language = XMLConstants.W3C_XML_SCHEMA_NS_URI; SchemaFactory factory = SchemaFactory.newInstance(language); schema = factory.newSchema(new File(name)); } catch (Exception e) { System.out.println(e.toString()); } return schema; } private static class MyErrorHandler implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { System.out.println("Warning: "); printException(e); } public void error(SAXParseException e) throws SAXException { System.out.println("Error: "); printException(e); } public void fatalError(SAXParseException e) throws SAXException { System.out.println("Fattal error: "); printException(e); } private void printException(SAXParseException e) { errorCount++; System.out.println(" Line number: "+e.getLineNumber()); System.out.println(" Column number: "+e.getColumnNumber()); System.out.println(" Message: "+e.getMessage()); System.out.println(); } } }
If you run it with in JDK environment to load hello.xsd, and validate hello.xml, you should see no validation errors.
herong> java XsdSchemaValidator hello.xsd hello.xml Passed.
Obviously, the above program will not work, if the XML Schema document is specified insided the XML document.
One way to perform the schema validation on an XML document with schema location assigned inside the XML document, is to use the Xerces2 API: XMLReader, SAXParser, and other interfaces and classes. Here is a tutorial example of how to use Xerces XMLReader and SAXParser directly:
/* XercesSchemaValidator.java - Copyright (c) 2002-2013 HerongYang.com. All Rights Reserved. */ import java.io.IOException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.apache.xerces.parsers.SAXParser; class XercesSchemaValidator { private static int errorCount = 0; public static void main(String[] a) { if (a.length<1) { System.out.println("Usage:"); System.out.println("java XercesSchemaValidator xml_file"); } else { String name = a[0]; validateXml(name); } } public static void validateXml(String name) { try { String parserClass = "org.apache.xerces.parsers.SAXParser"; String schemaFeature = "http://apache.org/xml/features/validation/schema"; // getting Xerces SAX parser as an XMLReader XMLReader parser = XMLReaderFactory.createXMLReader(parserClass); // setting the parser for XML schema validation parser.setFeature(schemaFeature,true); parser.setErrorHandler(new MyErrorHandler()); System.out.println(); System.out.println("Parsing and validating: "+name); parser.parse(name); System.out.println(); if (errorCount>0) { System.out.println("Failed with errors: "+errorCount); } else { System.out.println("Passed."); } } catch (Exception e) { // catching all exceptions System.out.println(); System.out.println(e.toString()); } } private static class MyErrorHandler extends DefaultHandler { public void warning(SAXParseException e) throws SAXException { System.out.println("Warning: "); printException(e); } public void error(SAXParseException e) throws SAXException { System.out.println("Error: "); printException(e); } public void fatalError(SAXParseException e) throws SAXException { System.out.println("Fattal error: "); printException(e); } private void printException(SAXParseException e) { errorCount++; System.out.println(" Line number: "+e.getLineNumber()); System.out.println(" Column number: "+e.getColumnNumber()); System.out.println(" Message: "+e.getMessage()); System.out.println(); } } }
To run the above program, you need to download Xerces2 package and prepare a batch script to include Xerces2 JAR files in the classpath.
herong> type java_xerces.bat java -cp .;.\xerces-2_12_1-xml-schema-1.1\xml-apis.jar; ^^^.\xerces-2_12_1-xml-schema-1.1\xercesImpl.jar; ^^^.\xerces-2_12_1-xml-schema-1.1\serializer.jar; ^^^.\xerces-2_12_1-xml-schema-1.1\resolver.jar.jar; ^^^.\xerces-2_12_1-xml-schema-1.1\org.eclipse.wst.xml.xpath2.processor_1.2.0.jar; ^^^.\xerces-2_12_1-xml-schema-1.1\cupv10k-runtime.jar; ^^^.\xerces-2_12_1-xml-schema-1.1\xercesSamples.jar; %1 %2 %3 %4 %5 %6
If you try this on hello.xml that has no schema location assigned, you will get an error:
herong> java_xerces XercesSchemaValidator.java hello.xml Parsing and validating: hello.xml Error: Line number: 2 Column number: 4 Message: cvc-elt.1: Cannot find the declaration of element 'p'. Failed with errors: 1
If you try this on hello_xsd_no_namespace.xml that has schema location assigned, you will get no errors:
herong> java_xerces XercesSchemaValidator.java hello_xsd_no_namespace.xml Parsing and validating: hello_xsd_no_namespace.xml Passed.
If you try this on hello_xsd_no_namespace.xml that has schema location assigned, you will get no errors:
herong> java_xerces XercesSchemaValidator.java hello_xsd_default_namespace.xml Parsing and validating: hello_xsd_default_namespace.xml Passed.
Table of Contents
XML Editor and Schema Processor - XMLPad
Java API for XML Processing - JAXP
JAXP - XML Schema (XSD) Validation
Xerces2 Java Parser - Java API of XML Parsers
Introduction of XSD Built-in Datatypes
"string" and Its Derived Datatypes
"decimal" and Its Derived Datatypes
"dateTime" and Its Related Datatypes
Miscellaneous Built-in Datatypes
Facets, Constraining Facets and Restriction Datatypes
"simpleType" - Defining Your Own Simple Datatypes
Identity-Constraints: unique, key and keyref
Assertion as Custom Validation Rules
►XML Schema Location and Namespace in XML Documents
Assigning XML Schema Location in XML Documents
►Validating XML Documents with Schema Locations
Validating XML Documents with Schema Locations - JAXP
Assigning XML Schema Location with Namespaces
Testing XML Schema Location with Namespaces
Testing XML Schema Location with Namespaces - JAXP
Overriding Element Types in XML Documents