We help IT Professionals succeed at work.

Retrieving useful error information when compiling an xsl stylesheet in Saxon 9.

1,143 Views
Last Modified: 2013-11-18
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

Comment
Watch Question

Top Expert 2009

Commented:
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.
Mick BarryJava Developer
CERTIFIED EXPERT
Top Expert 2010

Commented:

Author

Commented:
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
Top Expert 2009
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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

Top Expert 2009

Commented:
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 ;)
Top Expert 2009

Commented:
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 --

Author

Commented:
Sorry Abel.

I'm still not very familiar with the Experts Exchange conventions :)
Top Expert 2009

Commented:
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).
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.