Reputation: 454
I am trying to parse and validate an XML file against an RelaxNG schema using SAX. I have the following code:
System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory");
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
Schema schema = sf.newSchema(scf);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setSchema(schema);
try {
SAXParser parser = factory.newSAXParser ();
XMLReader reader = parser.getXMLReader ();
reader.setFeature("http://xml.org/sax/features/validation", true);
reader.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
schemaFilename);
reader.setFeature("http://apache.org/xml/features/xinclude", true);
reader.setFeature("http://xml.org/sax/features/namespaces", true);
reader.setFeature("http://apache.org/xml/features/xinclude/fixup-base-uris", false);
reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
reader.setErrorHandler (this);
reader.setContentHandler (this);
reader.setEntityResolver (this);
reader.parse (new InputSource(input));
but when I run this I get the error
Document is invalid: no grammar found.
The document and the schema both validate correctly using jing. Also, if I use trang to convert my schema to xsd and use that instead of rng, everything works correctly.
I suspect that when I instantiate the SAXParserFactory object I need to specify that I want a RelaxNG parser factory. The documentation on the relaxng.org site mentions "Can be used as a library for validation with any SAX2 parser", but the documentation link is broken. I have looked around the jing-trang-relaxng code and I cannot find a class with a name like '.*ParseFactory.*'
anywhere.
Any ideas on how to get this to work?
Upvotes: 0
Views: 177
Reputation: 167716
You can construct a ValidationHandler
from your Schema
e.g. ValidatorHandler validatorHandler = schema.newValidatorHandler();
. That ValidationHandler
can then be set on the XMLReader reader
as the ContentHandler
: reader.setContentHandler(validatorHandler);
. You can also set it as the DTDHandler
with e.g. reader.setDTDHandler((DTDHandler)validatorHandler);
.
Upvotes: 0