Re: James Clark releases new implementation of Schematron as part of Jing
James Clark <[email protected]> Fri, 20 Jun 2003 20:34:44 +0700
| Newsgroups | gmane.text.xml.schematron |
|---|---|
| Message-ID | <[email protected]> |
Rick Jelliffe wrote: > He seems to have some trick to allow instant death > when the first error is found; I expect this is a user option. Hmm. It's not supposed to do that. If the Schematron fails RELAX NG validation, then it won't try to compile it. But if the schema's OK, it should report all errors in the instance as normal. If you have a case where it doesn't, please send me a bug report. I wouldn't be surprised if there were bugs. > He has made his own > XSLT meta-stylesheet as well: he validates the Schematron schema using a RELAX NG > (consise syntax) schema, which means he can take most of the validation out of the > stylesheet. The meta-stylesheet has a couple of interesting features. One is the error reporting. Jing expects validators to report errors (both in the schema and the instance) via a SAX ErrorHandler, and I think it's highly desirable that these errors include line-numbers. The tactic I've adopted for getting line-numbers out of XSLT processors is to use extension functions. This works with Saxon and Xalan (at least with the current version). It could easily be made to work with XT. It can work with libxml/libxslt (with an extension function in Python). We can distinguish several different kinds of error: - Simple, structural errors in the schema. These are dealt with by RELAX NG validation. - More complex cross-reference errors in the schema (e.g. IDREFs pointing to the wrong kind of thing). We handle these by having the meta stylesheet detect these errors. For each error it detects, it generates an extension element in the XSLT. The output of applying the meta-stylesheet to the Schematron schema is run through a SAX ContentHandler that detects these extension elements and outputs a message through the ErrorHandler. - Errors in XPaths in the schema. Each start-tag in the output XSLT that contains an XPath that came from the Schematron schema is annotated with extension attributes giving the original line-number. The second stylesheet is compiled directly from the SAX events generated by the first stylesheet. The trick is that to insert a filter in between the output and the stylesheet compiler that reads the extension attributes and reports locations to the stylesheet compiler based on these extension attributes rather than the actual line-numbers in the generated stylesheet. The net result is that XPath errors are reported in terms of the original Schematron input. - Errors in the instance. The second transformation generates an XML document which contains an element for each message and these elements are annotated with line-column number. The second transformation feeds into a SAX content handler that outputs a message through the ErrorHandler. The meta-stylesheet also uses a different strategy from the reference implementation for compiling patterns and rules into a set of XSLT templates. The goal is improved efficiency. I haven't done enough testing to know whether it actually succeeds. It probably won't be noticeable in a client environment, where the running time seems to be dominated by Java overhead (startup and JIT time). There are two ideas underlying the strategy. One is to minimize the number of traversals of the XSLT tree. The other is to minimize the number of times you match a set of templates against a node. In the generated XSLT, there is a mode for each pattern and also a mode that combines all rules. There are two templates generated for each rule, one in its pattern's mode and one in the combined mode. The combined mode imposes an arbitrary order on the patterns and generates priorities to ensure no conflict. The combined mode is used to find the first rule that matches; the template in the combined mode then falls back to the per-pattern modes to ensure that the errors from all patterns are reported. This should be much more efficient with schemas that are "sparse" (i.e. there are many instance elements for which there are matching rules in few or no patterns): an instance element that doesn't match any rules can be handled using a single XSLT matching operation (as opposed to one matching operation for each pattern). There's one really hairy part on the Java side, which stems from the fact that JAXP XSLT interface wants to be in control of things (i.e. it only provides a transform() method that accepts a SAX XMLReader for the input and a SAX ContentHandler for the output). In the context of NRL, NRL needs to be in control: it needs to get a ContentHandler into which it can feed SAX events. This would also be the case in any context where you wanted to use Schematron to validate the output of a process rather than the input. I deal with this by using a separate thread to run the XSLT transformation as a coroutine. James ------------------------------------------------------- This SF.Net email is sponsored by: INetU Attention Web Developers & Consultants: Become An INetU Hosting Partner. Refer Dedicated Servers. We Manage Them. You Get 10% Monthly Commission! INetU Dedicated Managed Hosting http://www.inetu.net/partner/index.php