This section describes a tutorial example on how to the Xerces2 SAXParser class to validate an XML document assigned with an XSD file. The sample program SAXValidator.java works up to JDK 1.6. It is not working with JDK 1.7.
Xerces-J package can also be loaded by the SAXParserFactory.newInstance()
method to do XSD schema validation. Here is my sample program SAXValidator.java:
/* SAXValidator.java
- Copyright (c) 2013, HerongYang.com, All Rights Reserved.
*/
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
class SAXValidator {
public static void main(String[] args) {
String schemaFeature
= "http://apache.org/xml/features/validation/schema";
try {
File x = new File(args[0]);
SAXParserFactory f = SAXParserFactory.newInstance();
System.out.println(f.toString());
f.setValidating(true);
f.setFeature(schemaFeature,true);
SAXParser p = f.newSAXParser();
System.out.println(p.toString());
DefaultHandler h = new MyErrorHandler();
p.parse(x,h);
} catch (ParserConfigurationException e) {
System.out.println(e.toString());
} catch (SAXException e) {
System.out.println(e.toString());
} catch (IOException e) {
System.out.println(e.toString());
}
}
private static class MyErrorHandler extends DefaultHandler {
public void warning(SAXParseException e) throws SAXException {
System.out.println("Warning: ");
printInfo(e);
}
public void error(SAXParseException e) throws SAXException {
System.out.println("Error: ");
printInfo(e);
}
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("Fattal error: ");
printInfo(e);
}
private void printInfo(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());
}
}
}
Note that the schema feature is set to the SAXParserFactory object, not to the SAXParser object.
Running SAXValidator.java with JDK 1.4 and Xerces-J 2.3 in 2002:
Note that the default SAXParser in JDK 1.4 is the "crimson" implementation,
doesn't support XSD validation.
We need to run SAXValidator.java with Xerces-J 2.3 JAR file specified:
java -cp ".;\local\xerces-2_3_0\xercesImpl.jar"
SAXValidator dictrionary_invalid_xsd.xml
org.apache.xerces.jaxp.SAXParserFactoryImpl@f72617
org.apache.xerces.jaxp.SAXParserImpl@173831b
Error:
Public ID: null
System ID: file:///C:/herong/dictionary_invalid_xsd.xml
Line number: 7
Column number: 22
Message: cvc-datatype-valid.1.2.1: 'yes' is not a valid value for
'boolean'.
...
Conclusion: my SAXValidator.java can be used with the "Xerces-J 2.3" implementation of SAXParser
to validate XML documents with XSD schema.
Running SAXValidator.java with JDK 1.6 and Xerces2 2.9.1 in 2009:
I am getting the same result as JDK 1.4 with Xerces-J 2.3.
Running SAXValidator.java with JDK 1.7 and Xerces2 2.11.0 in 2013:
c:\Progra~1\Java\jdk1.7.0_07\bin\javac XMLReaderValidator.java
c:\Progra~1\Java\jdk1.7.0_07\bin\java
SAXValidator dictionary_invalid_xsd.xml
com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl@e86da0
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl@17c2891
Error:
Public ID: null
System ID: file:/C:/herong/dictionary_invalid_xsd.xml
Line number: 3
Column number: 49
Message: cvc-elt.1: Cannot find the declaration of element 'dictionary'.
Notice that the default SAXParser in JDK 1.7 is the "xerces" implementation.
But it is not able to load the XSD document specified in the XML document as:
xsi:noNamespaceSchemaLocation="dictionary.xsd"