Retrieving useful error information when compiling an xsl stylesheet in Saxon 9.
I am developing an application that uses Saxon 9 to transform XML with XSL stylesheets. I have so far been unable to extract useful stylesheet error information when an exception has been raised.
The Saxon 9 command-line utility produces very helpful error information including line numbers, diagnostics, etc, so I'm assuming that it is possible to extract the information through the java api somehow.
I've had a look at the various ErrorListener classes and related methods, but they only seem to deal with errors at transformation time. I may simply be after a nice way to run validation on the stylesheet text when I catch a javax.xml.transform.TransformerConfigurationException when compiling the stylesheet, but I've had no luck finding validation inside the Saxon classes either.
If I could get an example of extracting a stylesheet's error information during the compile phase that would be excellent.
import net.sf.saxon.*;import javax.xml.transform.*;import javax.xml.transform.dom.*TransformerFactoryImpl fact = new TransformerFactoryImpl();DOMSource source = ...;// an XML document, already validated as XML// to be used as the XSL stylesheettry { fact.newTransformer(source); // } catch(TransformerConfigurationException error) { // I would like to extract xsl-related errors here}
I will forward your question to the Saxon mailing list. Often, Michael Kay himself answers on that list quite promptly. If you are interested yourself in the answers, you can subscribe to that list through the Saxon Sourceforge pages.
The solution you provided with the ErrorListener on the TransformerFactory has allowed me to extract some useful information, but doesn't give me any line numbers.
The error string that I extract from the ListeningErrorListener is:
--- begin
:Line=-1;Column=-1: exception:Unknown XSLT element: george
root-cause:null
line: logSourceLine unavailable due to: no protocol:
error: Unknown XSLT element: george
--- end
Any idea how I can track down the line number as well?
// import java.io.*;// import org.apache.xml.utils.ListingErrorHandler;// import javax.xml.transform.TransformerConfigurationException;StringWriter writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ListingErrorHandler errorListener = new ListingErrorHandler(PrintWriter);// net.sf.saxon.TransformerFactoryImpl tFactory;tFactory.setErrorListener(errorListener);try { // javax.xml.transform.dom.DOMSource source; tFactory.newTransformer(source)} catch(TransformerConfigurationException error) { // extract a useful error message writer.toString();}
weren't you a bit quick with grading (esp a B) when you still had questions on how to solve it? I'll like to look into it for you, but it is 4AM here, so it'll be a short while later ;)
abel
Getting the line number is not so trivial and depends on whether the source document has line number information already or not. Here's a post from, again, Michael Kay about the subject:
It turns out that there is in fact a class net.sf.saxon.event.LocationCopierwhich is designed to copy line number information.I think that if you do the following, any line number information present inthe source document nodeInfo should be passed across to the new document:PipelineConfiguration pipe = config.makePipelineConfiguration();Builder b = new TinyBuilder();b.setPipelineConfiguration(pipe);b.setLineNumbering(true);LocationCopier lc = new LocationCopier();lc.setUnderlyingReceiver(lc);lc.setPipelineConfiguration(pipe);nodeInfo.copy(lc, NodeInfo.ALL_NAMESPACES, true, 0);The schema document builder automatically inserts a LocationCopier into thepipeline. In fact, that's what LocationCopier was designed for - it's usedwhen processing the inline schema that can be contained in anxsl:import-schema element in a stylesheet. I tested this with the followingsimple program: public static void main(String[] args) throws Exception { Configuration config = new SchemaAwareConfiguration(); config.setLineNumbering(true); NodeInfo node = config.buildDocument(new StreamSource(newFile("c:/temp/test.xsd"))); config.addSchemaSource(node); }and confirmed that errors in the schema are reported with line numbers.But this only works, of course, if the source document already contains linenumber information.
I'm still not very familiar with the Experts Exchange conventions :)
abel
np. The idea is, usually, the interrogate "your" expert or "experts" and to burden them with questions until you are satisfied. Of course, the questions must remain in the scope of the original question.
It is custom to give A when you are satisfied with the answer (not necessary the result: sometimes something "cannot be done" but, rightfully argumented, that should still receive an A grade).
Reserve B when you tried to get your answer but the expert just isn't capable of completely satisfying you or does not return often (i.e., waits longer than a day or so)
Reserve C (is it still available) when you are actually dissatisfied, but the answer was to some aid to you. Often, when you consider a C you should also consider deleting the question, or answering it yourself (post a Q. in the customer topic area to give yourself the credits).