An implementation of Relax NG schema validation written in Common Lisp, including support for compact syntax, DTD Compatibility, and the XSD type library.
cxml-rng was written by David Lichteblau and is designed as an add-on library for Closure XML. It is available under an X11-style license.
Please send bug reports to cxml-devel@common-lisp.net (list information).
Download and Installation
Download a cxml-rng tarball.
cxml-rng needs Closure XML, CL-PPCE, CL-Yacc, parse-number, and cl-base64. ASDF is used for compilation. Register the .asd file, e.g. by symlinking it, then compile cxml-rng using asdf:operate.
$ ln -sf `pwd`/cxml-rng.asd /path/to/your/registry/ * (asdf:operate 'asdf:load-op :cxml-rng)
Implementation-specific notes
At this point, cxml-rng is written to work with Lisp strings (as opposed to runes and rods), and is meant to be used on Lisp implementations with Unicode support.
Example
Use cxml-rng:parse-schema to parse a Relax NG schema file. The resulting schema object is a representation of a simplified schema using Lisp objects, which has gone through simplification as described the Relax NG specification. cxml-rng:serialize-schema can be used to write a Relax NG file in XML syntax for this grammar.
In order to validate XML against a schema, create a validation handler for the grammar using cxml-rng:make-validator. The validation handler processes SAX events and can be used with any function generating such events, in particular with cxml:parse-file.
(cxml:parse-file "example.xml"
(cxml-rng:make-validator
(cxml-rng:parse-schema #p"example.rng")))
The validator accepts another SAX handler as an optional second argument. For example, to parse XML into DOM while also validating it, use the validator like this:
(cxml:parse-file "example.xml" (cxml-rng:make-validator (cxml-rng:parse-schema #p"example.rng") (cxml-dom:make-dom-builder)))
When using the klacks parser, create a validating source.
(klacks:with-open-source
(s (cxml-rng:make-validating-source
#p"example.xml"
(cxml-rng:parse-schema #p"example.rng")))
(loop for key = (klacks:peek-next s) while key do (print key)))
DTD Compatibility processing (basically, checking of IDs and addition of default values) is done using a DTD Compatibility handler. You can use this handler together with a validator or by its own.
(cxml:parse-file "example.xml" (cxml-rng:make-dtd-compatibility-handler (cxml-rng:parse-schema #p"example.rng") (cxml-dom:make-dom-builder)))
Documentation
API documentation is available.