Saxon Jing is a small open source Java library bridging the Saxon Processor with James Clark's Jing Validator enabling one to validate XML documents against Compact Syntax RelaxNG Schemas in XSLT and XQuery via XPath Functions.
If you need to validate thousands of documents against a RelaxNG Schema or need to add RelaxNG validation into your existing XML based workflow this could come in handy.
declare namespace rng = "http://relaxng.org/ns/structure/1.0"; declare function rng:schema( $uri as xs:string ) as function(node()) as empty-sequence() external; declare function rng:schema-report( $uri as xs:string ) as function(node()) as element(report) external;
The $uri
parameter
can either be a path to a RelaxNG Schema on disk (relative or absolute) or a
fully qualified URI to a resource, for instance a HTTP URL or a JAR reference.
Calling either one of these functions will fetch and compile the
RelaxNG Schema and subsequently return a function which takes
either a document-node()
or an element()
node.
This returned function is essentially a validator which you can use as many times as you like over as many documents as you like within the same XSLT or XQuery process. The Schema is only compiled once!
The function produced from rng:schema
returns an empty-sequence()
if validation
against the node was successful but will throw an error if the document was invalid.
The function produced from rng:schema-report
will return a report
element which details
all validation issues (if any) that occurred whilst validating a document,
exactly what the errors were and where they were found. This function should
never throw an error and a successful validation will simply produce
an empty <report />
element.
A failed report element, will look something along the lines of:
<report> <error> <message column-number="20" line-number="2"> character content of element "date" invalid; must be an ISO date </message> <message column-number="24" line-number="3"> character content of element "integer" invalid; must be an integer </message> <message column-number="10" line-number="4"> element "blurb" not allowed anywhere; expected element "text" </message> <message column-number="8" line-number="5"> element "data" incomplete; missing required element "text" </message> </error> </report>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rng="http://relaxng.org/ns/structure/1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="rng fn" version="3.0"> <xsl:template name="xsl:initial-template"> <!-- Validate!, returns empty-sequence() OR throws error --> <xsl:variable name="schema" as="function(node()) as empty-sequence()" select="rng:schema('my-schema.rnc')" /> <xsl:sequence select="$schema(fn:doc('hello-world.xml'))" /> <!-- Report!, returns report element --> <xsl:variable name="report" as="function(node()) as element(report)" select="rng:schema-report('my-schema.rnc')" /> <xsl:sequence select="$report(fn:doc('hello-world.xml'))" /> </xsl:template> </xsl:stylesheet>
There are more examples for both XSLT and XQuery at: https://github.com/cfoster/saxon-jing/tree/master/examples
3 libraries or jar files need to exist on the classpath.
When running Saxon directly from the command line to run either
XSLT or XQuery, you need to tell Saxon how to find the
XPath functions via the -init
argument.
Consider the following example:
java -cp jing-20091111.jar;saxon9ee.jar;saxon-jing-0.9.2.jar \ net.sf.saxon.Transform -init:net.cfoster.saxonjing.JingInitializer \ -s:my-source.xml -xsl:my-stylesheet.xsl -o:out.xml
If you wish to use Saxon's S9 API to invoke XSLT or XQuery which has access to Saxon Jing, you will need to register the External Functions like so:
// imports import net.sf.saxon.s9api.Processor; import net.cfoster.saxonjing.SchemaFunction; import net.cfoster.saxonjing.SchemaReportFunction; // key code Processor proc = new Processor(false); proc.registerExtensionFunction(new SchemaFunction()); proc.registerExtensionFunction(new SchemaReportFunction(proc));
There are Scala tests which invoke XSLTs which are Jing Aware in the project's test suite.
You can let Saxon know about the Jing XPath functions in a configuration file, or by subclassing net.sf.saxon.Transform or net.sf.saxon.Query, there are quite a few approaches. Please refer to the Saxon Documentation for further details.
To run from oXygen, you will need to add both the Jing and Saxon Jing
.jar
libraries as Extensions to your XSLT or XQuery Scenario as well as
setting the Initializer Class to "net.cfoster.saxonjing.JingInitializer"
.
Error Code | Reason |
---|---|
RNGE0001 | Jing can not be found on Classpath |
RNGE0002 | Syntax Error in Relax NG Schema |
RNGE0003 | Could not find Relax NG Schema |
RNGE0004 | Generic Exception whilst trying to load RelaxNG Schema |
RNGE0005 | Schema Validation Failed |
RNGE0006 | Unknown Exception |
Source is available on GitHub at https://github.com/cfoster/saxon-jing. Contributations are welcome!
This software is released under the Apche 2.0 Licence.