opeongo
opeongo

Reputation: 454

Validating XML with RelaxNG and SAX

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

Answers (1)

Martin Honnen
Martin Honnen

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

Related Questions