Bali Java Validatelet

$Id: java.html,v 1.4 2002/09/30 17:06:17 Bear Exp $
By Kohsuke KAWAGUCHI

Generating a validatelet

To compile myschema.rng into the org.acme.MyValidatelet in the src folder, type in as follows:

$ java -jar bali.jar myschema.rng -oj src org.acme.MyValidatelet

This will produce ./src/org/acme/MyValidatelet.java along with a couple of other files that are necessary to run this validatelet.

Writing code to use validatelet

Through JARV

Next, you need to write code that uses this validatelet. The simplest way is to use JARV interface that gives you high-level access to validation (such as validating a DOM tree, file, or using it as an XMLFilter etc.) For details about using JARV, consult to this document.

Typical code would look like follows:

// wrap a compiled schema into JARV schema object
org.iso_relax.verifier.Schema schema
  = new org.kohsuke.bali.validatelet.jarv.JARVSchemaImpl(org.acme.MyValidatelet.schema);

// next, create a verifier
org.iso_relax.verifier.Verifier verifier = schema.newVerifier();

// then have fun with it. for example,...
if( !verifier.verify(new File(...)) )
  System.out.println("not valid");

Through SAX

If you are comfortable with working with SAX or you don't want to have isorelax.jar around for some reason, you could use the generated validatelet directly. All the generated validatelets implement Validatelet. This interface extends SAX ContentHandler, so the basic client programming model is to send SAX events to a validatelet.

You can set a SAX ErrorHandler to a validatelet to receive validation errors. If you don't set one, it will simply throw a SAXParseException upon an error.

Typical code in this case would look like this:

// create a new instance of validatelet
org.kohsuke.validatelet.Validatelet  v = new org.acme.MyValidatelet();

// set an error handler to receive errors.
v.setErrorHandler( errorHandler );

reader.setContentHandler(v);
reader.parse(something);

Required JAR Files at Run-time

Firstly, you need to have validatelet.jar file in your classpath when you run an application that uses validatelets. This jar file just contains the Validatelet interface, which provides the common base type for all the validatelets. This makes it possible to write code that equally accepts any validatelet. I solicit any comment as to whether this benefit justifies requring a jar file at run-time.

If you use JARV as your client API, you also need to have isorelax.jar in your classpath. This jar file can be found in the lib directory of the distribution.

Furthermore, if your schema uses a datatype library (such as W3C XML Schema datatypes), then you need to have an implementation of that library in your classpath, too. For W3C XML Schema Datatypes, you can either use Sun XML Datatypes Library or one found inside Jing. In general, you can use any datatype library as long as it supports the org.relaxng.datatype interfaces.

Limitation

  1. Because of the validation algorithm, the generated validatelet is not necessarily a fail-fast validator. This is, when you read a start element, it doesn't validate all the attributes immediately. Thus if you write your code in such a way that you'll access attributes at the start element, that code could be vulnerable to invalid documents.
  2. A validatelet doesn't support recovery from an error. After reporting the first error, it simply stops validation.