Link to home
Start Free TrialLog in
Avatar of BSDev
BSDev

asked on

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 stylesheet
 
try {
    fact.newTransformer(source); // 
} catch(TransformerConfigurationException error) {
    // I would like to extract xsl-related errors here
}

Open in new window

Avatar of abel
abel
Flag of Netherlands image

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.
Avatar of Mick Barry
Avatar of BSDev
BSDev

ASKER

objects:

"Failed to compile stylesheet. 1 error detected"

... is all I seem to be able to retrieve with getMessageAndLocation().

I've looked at most of the exception methods, and don't seem to be able to get anything useful back from them.

For reference I'm using this block of XSL text to test with:

--- begin

               
           
           
                  
                      <!-- error -->
                      
                   
                   
               
           
       
--- end
ASKER CERTIFIED SOLUTION
Avatar of abel
abel
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of BSDev

ASKER

abel:

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();
}

Open in new window

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 ;)
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.

Regards,
-- Abel --
Avatar of BSDev

ASKER

Sorry Abel.

I'm still not very familiar with the Experts Exchange conventions :)
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).