This section describes a tutorial example on how to validate an XML document with schema location assigned inside the XML document using Xerces API.
It will make some XML schema validation tool happier, if the schema location is assigned inside an XML document.
However, if you are writing a Java program with JAXP 1.4 to perform the validation, it becomes harder.
This is because JAXP 1.4 standard recommends you to provide the schema separately from the XML document dynamically
at the time of validation, instead of statically assigned inside the XML document.
In order to perform the schema validation on an XML document with schema location assigned inside the XML document,
we need to use the original 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) 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();
}
}
}
If you try this on hello.xml that has no schema location assigned,
you will get an error:
>javac -classpath .;\local\xerces-2_9_1\xercesImpl.jar
XercesSchemaValidator.java
>java -classpath .;\local\xerces-2_9_1\xercesImpl.jar
XercesSchemaValidator 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:
>java -classpath .;\local\xerces-2_9_1\xercesImpl.jar
XercesSchemaValidator hello_xsd_no_namespace.xml
Parsing and validating: hello_xsd_no_namespace.xml
Passed.
Conclusion:
Assigning the schema location inside XML documents, and performing schema validation while parsing XML documents
in not recommended by JAXP (Java API for XML Processing) any more.
JAXP recommends to load the schema separately, and perform schema validation on XML documents as an independent
function separated from the parsing function.
The Xerces SAXParser still supports schema validation on XML documents with schema locations assigned inside XML
documents.