package com.skaringa.util;
import java.io.IOException;
import java.io.PrintStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
/**
* Check if an XML file is valid
*/
public final class SAXValidator {
/** Constants used for JAXP 1.2 */
static final String JAXP_SCHEMA_LANGUAGE =
"http://java.sun.com/xml/jaxp/properties/schemaLanguage";
static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
static final String JAXP_SCHEMA_SOURCE =
"http://java.sun.com/xml/jaxp/properties/schemaSource";
/**
* Validate an XML instance against an schema.
* @param xmlSource The source of the instance.
* @param schemaSource The source of the schema.
* @throws SAXException If the instance doesn't validate.
* @throws IOException If reading the instance or schema failes.
* @throws ParserConfigurationException If the parser isn't validating.
*/
public static void validate(InputSource xmlSource, InputSource schemaSource)
throws
SAXException,
IOException,
ParserConfigurationException {
// Create a JAXP SAXParserFactory
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
// Create a JAXP SAXParser
SAXParser saxParser = spf.newSAXParser();
// Set the schema language
saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
// Set the schema source.
saxParser.setProperty(JAXP_SCHEMA_SOURCE, schemaSource);
// Get the SAX XMLReader
XMLReader xmlReader = saxParser.getXMLReader();
// Set the ErrorHandler
xmlReader.setErrorHandler(new MyErrorHandler(System.err));
// Parse the XML source
// This will throw a SAXException if the file is not valid.
xmlReader.parse(xmlSource);
}
/**
* Error handler to report errors and warnings.
*/
private static final class MyErrorHandler implements ErrorHandler {
/** Error handler output goes here */
private PrintStream _out;
/**
* Construct MyErrorHandler.
* @param out The stream where messages are printed.
*/
MyErrorHandler(PrintStream out) {
_out = out;
}
/**
* Returns a string describing parse exception details.
* @param spe The parse exception.
* @return Description of parse exception details.
*/
private String getParseExceptionInfo(SAXParseException spe) {
String systemId = spe.getSystemId();
if (systemId == null) {
systemId = "null";
}
String info =
"URI="
+ systemId
+ " Line="
+ spe.getLineNumber()
+ ": "
+ spe.getMessage();
return info;
}
// The following methods are standard SAX ErrorHandler methods.
// See SAX documentation for more info.
/**
* @see ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException spe) throws SAXException {
_out.println("Warning: " + getParseExceptionInfo(spe));
}
/**
* @see ErrorHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException spe) throws SAXException {
String message = "Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
/**
* @see ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException spe) throws SAXException {
String message = "Fatal Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
}
/**
* Hide ctor because this is an utility class.
*/
private SAXValidator() {
}
}