What's the best way to validate an XML file against an XSD file?
The Java runtime library supports validation. Last time I checked this was the Apache Xerces parser under the covers. You should probably use a javax.xml.validation.Validator.
import javax.xml.XMLConstants;import javax.xml.transform.Source;import javax.xml.transform.stream.StreamSource;import javax.xml.validation.*;import java.net.URL;import org.xml.sax.SAXException;//import java.io.File; // if you use Fileimport java.io.IOException;...URL schemaFile = new URL("http://host:port/filename.xsd");// webapp example xsd: // URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");// local file example:// File schemaFile = new File("/location/to/localfile.xsd"); // etc.Source xmlFile = new StreamSource(new File("web.xml"));SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);try { Schema schema = schemaFactory.newSchema(schemaFile); Validator validator = schema.newValidator(); validator.validate(xmlFile); System.out.println(xmlFile.getSystemId() + " is valid");} catch (SAXException e) { System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);} catch (IOException e) {}
The schema factory constant is the string http://www.w3.org/2001/XMLSchema
which defines XSDs. The above code validates a WAR deployment descriptor against the URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
but you could just as easily validate against a local file.
You should not use the DOMParser to validate a document (unless your goal is to create a document object model anyway). This will start creating DOM objects as it parses the document - wasteful if you aren't going to use them.
Here's how to do it using Xerces2. A tutorial for this, here (req. signup).
Original attribution: blatantly copied from here:
import org.apache.xerces.parsers.DOMParser;import java.io.File;import org.w3c.dom.Document;public class SchemaTest { public static void main (String args[]) { File docFile = new File("memory.xml"); try { DOMParser parser = new DOMParser(); parser.setFeature("http://xml.org/sax/features/validation", true); parser.setProperty( "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", "memory.xsd"); ErrorChecker errors = new ErrorChecker(); parser.setErrorHandler(errors); parser.parse("memory.xml"); } catch (Exception e) { System.out.print("Problem parsing the file."); } }}
We build our project using ant, so we can use the schemavalidate task to check our config files:
<schemavalidate> <fileset dir="${configdir}" includes="**/*.xml" /></schemavalidate>
Now naughty config files will fail our build!