Java schema validation with JAXP/Xerces

Schema validation is a problem that comes up from time to time, and I learned some gotchas with using the JAXP api.

Our XSD schema was relatively complex, and included other XSD schemas, which made it a little trickier than the “Hello World” examples you can find around the web. I started with the goal of loading all schemas from the test resources folder. SchemaFactory has a setResourceResolver method that takes an implementation of LSResourceResolver, which looked promising. However, when my custom, classpath-resource-loading implementation was set, the SchemaFactory looped infinitely while trying to load nested XSDs, and ran out of memory. It seems that there are some undocumented nuances for implementing these ResourceResolvers.

Instead, I decided to move the XSDs to a known location under the project (etc). The next gotcha was the newSchema method. When passed a stream, it has errors resolving referenced XSDs (with relative paths), but when passed a File, there’s no problem. However, the documentation claims that the newSchema(File) is just a convenience method for newSchema(Source).

This is the final code. A SAXException with a message indicating the problem is thrown if there’s a validation error.

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import junit.framework.TestCase;

public class SchemaValidationTest extends TestCase {

	private static final String SCHEMA_FILE = "mySchema.xsd";
	private static final String XML_RESOURCE = "myDocument.xml";

	public void testValidate() throws Exception  {
		SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		Schema schema = factory.newSchema(new File(SCHEMA_FILE));

		Validator validator = schema.newValidator();
		validator.validate(new StreamSource(getClass().getResourceAsStream(XML_RESOURCE)));
	}

}
It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply