You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xalan.apache.org by Don McClimans <dm...@IntiElectronics.com> on 2003/01/08 17:51:34 UTC

Getting the line and column number of an error

I want to show the line and column number any errors that occur during a
transform. Is there an easy way to do this?

I looked at Xalan.exe, which does report this information. But it's not in
the return string from getLastError(), rather, XalanTransformer::transform()
seems to dump this information to cout or cerr. I guessed that this was
being done by the ProblemListener that is part of a XalanTransformer, but
when I call getProblemListnere(), it returns null.

I've browsed around the API docs for ProblemListener and
XalanTransformerProblemListener, but I haven't groked the "big picture" to
know what I should be using when. It seems like this should be simple, but
I'm confused. Please point me in the right direction! :)

Thanks,

Don McClimans


RE: Getting the line and column number of an error

Posted by Don McClimans <dm...@IntiElectronics.com>.
>>In my application, my custom problemListener is never called, and
>>XalanTransformer::getLastError() returns:
>>	Invalid character (Unicode: 0x4)
>>
>>So I'm back to wondering how to get the line number of the error.
>
>This does the trick for us (and you cannot get much shorter code):
>
>    catch (XSLException& e) {
>        std::cerr << e.defaultFormat().transcode().begin()) << std::endl;
>    }

I don't understand what you mean. XalanTransformer::transform() is not
throwing an exception, so how can adding a catch do anything?

Don


RE: Getting the line and column number of an error

Posted by Juergen Hermann <jh...@web.de>.
On Tue, 21 Jan 2003 15:45:38 -0500, Don McClimans wrote:

>In my application, my custom problemListener is never called, and
>XalanTransformer::getLastError() returns:
>	Invalid character (Unicode: 0x4)
>
>So I'm back to wondering how to get the line number of the error.

This does the trick for us (and you cannot get much shorter code):

    catch (XSLException& e) {
        std::cerr << e.defaultFormat().transcode().begin()) << std::endl;
    }


Ciao, Jürgen

--
Jürgen Hermann, Developer
WEB.DE AG, http://webde-ag.de/



RE: Getting the line and column number of an error

Posted by David N Bertoni/Cambridge/IBM <da...@us.ibm.com>.



Hi Don,

There's no nightly build, but if you get the latest code from CVS and build
it yourself, you should see these coming through.  Unfortunately, due to
our convoluted error handling mechanism, they are coming through as
warnings, and not errors.  )Yet another reason why it needs to be
overhauled.)

Dave



                                                                                                                         
                      "Don McClimans"                                                                                    
                      <dmcclimans@IntiElect         To:      <xa...@xml.apache.org>                              
                      ronics.com>                   cc:      (bcc: David N Bertoni/Cambridge/IBM)                        
                                                    Subject: RE: Getting the line and column number of an error          
                      01/21/2003 12:45 PM                                                                                
                                                                                                                         



Dave,

I'm back with more questions about error handling...

I accidentally generated a source file with a 0x04 character in the text of
an element (UTF-8 encoding). Xalan (correctly) does not like this. When I
run the command line xalan.exe, I get the message:
             Fatal Error at (file test.txt, line 15729, column 24): Invalid
character
 Unicode: 0x4)
             Invalid character (Unicode: 0x4)

In my application, my custom problemListener is never called, and
XalanTransformer::getLastError() returns:
             Invalid character (Unicode: 0x4)

So I'm back to wondering how to get the line number of the error.

I tried creating a std::ostringstream, and calling
XalanTransformer::setWarningStream with it. Unfortunately, no message is
stored in the ostringstream. Browsing the xalan code, this has me confused,
as it looks like that's where the first message ("Fatal error...") above is
coming from in the xalan.exe example. Should this work?

I'm now running the 2002/10/21 interim release. Should I upgrade to the
latest nightly build to (presumably) get your fix to return the line number
in getLastError()? How stable is this? I need something that I can release
to others.

Or is there another way to get at that information?

Thanks for any help you can give me.

Don




RE: Getting the line and column number of an error

Posted by Don McClimans <dm...@IntiElectronics.com>.
Dave,

I'm back with more questions about error handling...

I accidentally generated a source file with a 0x04 character in the text of
an element (UTF-8 encoding). Xalan (correctly) does not like this. When I
run the command line xalan.exe, I get the message:
	Fatal Error at (file test.txt, line 15729, column 24): Invalid character
 Unicode: 0x4)
	Invalid character (Unicode: 0x4)

In my application, my custom problemListener is never called, and
XalanTransformer::getLastError() returns:
	Invalid character (Unicode: 0x4)

So I'm back to wondering how to get the line number of the error.

I tried creating a std::ostringstream, and calling
XalanTransformer::setWarningStream with it. Unfortunately, no message is
stored in the ostringstream. Browsing the xalan code, this has me confused,
as it looks like that's where the first message ("Fatal error...") above is
coming from in the xalan.exe example. Should this work?

I'm now running the 2002/10/21 interim release. Should I upgrade to the
latest nightly build to (presumably) get your fix to return the line number
in getLastError()? How stable is this? I need something that I can release
to others.

Or is there another way to get at that information?

Thanks for any help you can give me.

Don


RE: Getting the line and column number of an error

Posted by David N Bertoni/Cambridge/IBM <da...@us.ibm.com>.



Hi Don,

No problem, glad it works now.  I've also added some enhancements so we
catch SAXParseException and report Locator information (line number, column
number, and system ID).

And finally someone else has confirmed my status as the world's most
under-appreciated software engineer!  I've been trying for years to get my
manager to recognize this.  ;-)

Dave



                                                                                                                                      
                      "Don McClimans"                                                                                                 
                      <dmcclimans@IntiElect         To:      <xa...@xml.apache.org>                                           
                      ronics.com>                   cc:      (bcc: David N Bertoni/Cambridge/IBM)                                     
                                                    Subject: RE: Getting the line and column number of an error                       
                      01/11/2003 08:41 AM                                                                                             
                                                                                                                                      



I set up my own problemListener, and this works fine. Thanks, Dave,
for your help. And for all your under-appreciated work. :)

Don





RE: Getting the line and column number of an error

Posted by Don McClimans <dm...@IntiElectronics.com>.
I set up my own problemListener, and this works fine. Thanks, Dave, 
for your help. And for all your under-appreciated work. :)

Don



RE: Getting the line and column number of an error

Posted by David N Bertoni/Cambridge/IBM <da...@us.ibm.com>.



Hi Don,

> >You can set the ProblemListener for the XalanTransformer instance, and
most
> >errors (but not all, unfortunately) will come through the call.  See the
> >classes ProblemListenerDefault and XalanTransformerProblemListener for
more
> >information.  The purpose of the latter is to allow re-direction of
> >warnings to a stream specified by the user.

> I've looked at these classes, but how do I use them? Can I use these
classes
> as is, or do I need to derive my own class from ProblemListener to cache
the
> line and column number information?

You would probably want to derive your own.  ProblemListenerDefault writes
characters to a supplied stream.  The default operation in XalanTransformer
is to give DefaultProblemListener a stream that appends character to a
XalanDOMString.  This string is what's returned from getLastError(), if any
data was written to it.  If not, XalanTransformer asks the exception for
the character string it contains.  You probably want to doing something
different, so you can just derive from ProblemListener and do what you want
with the data it gets.

> From the behavior of XalanTransformer::transform(), which is to write the
> error message to cerr (I think), I assumed that a DefaultProblemListener
> exists and is part of my XalanTransformer object. But if that is so, why
> do I get a null return from getProblemListener?

It's a transient stack-based object, so it's not a member of the class.
XalanTransformer::getProblemListener() only returns a pointer to the
ProblemListener instance installed by the user.

> Hmm, I don't think I ever see line number information from getLastError,
for
> any error. At any rate, it's easy to create the problem. Here's a simple
> stylesheet:
>
>   <?xml version="1.0" encoding="UTF-8"?>
>   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="1.0">
>     <xsl:template match="@*|node()">
>       <xsl:apply-templates select="@*|node()">
>     </xsl:template>
>   </xsl:stylesheet>

Ahh yes, a SAX parsing error.  This is a bug, but there's no real
workaround for it -- it's just part of the whole problem we have dealing
with multiple exception hierarchies and multiple error handling mechanisms.
However, the line number information will come through in the
ProblemListener call, and also will come through in the warning that's
written to the stream.  Yes, this comes through as a warning in the
ProblemListener, because if it were to come through as an error, the
ExecutionContext instance would be obliged to throw its own exception,
rather then let the parsing code throw the appropriate SAX exception.

Needless to say, I really want to clean up the ProblemListener/error
reporting stuff so exceptions are thrown at the point where the error
occurred, and not the ExecutionContext.  The code is quite schizophrenic
right now, because some exceptions are thrown from the code where the error
occurred, while others are thrown from the ExecutionContext.  This is an
ongoing problem.  Sigh...

I also see that we're not passing the line number information on to the
SAXParseException, so if I fix that problem, at least the error message
could contain the line information.

Hope that helps...

Dave


RE: Getting the line and column number of an error

Posted by Don McClimans <dm...@IntiElectronics.com>.
>You can set the ProblemListener for the XalanTransformer instance, and most
>errors (but not all, unfortunately) will come through the call.  See the
>classes ProblemListenerDefault and XalanTransformerProblemListener for more
>information.  The purpose of the latter is to allow re-direction of
>warnings to a stream specified by the user.

I've looked at these classes, but how do I use them? Can I use these classes
as is, or do I need to derive my own class from ProblemListener to cache the
line and column number information? From the behavior of
XalanTransformer::transform(), which is to write the error message to cerr
(I think), I assumed that a DefaultProblemListener exists and is part of my
XalanTransformer object. But if that is so, why do I get a null return from
getProblemListener?

>However, since errors which have line number information should have that
>information in the string returned by getLastError(), this may be a bug.
>Can you describe what sort of error it is?

Hmm, I don't think I ever see line number information from getLastError, for
any error. At any rate, it's easy to create the problem. Here's a simple
stylesheet:

  <?xml version="1.0" encoding="UTF-8"?>
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
    <xsl:template match="@*|node()">
      <xsl:apply-templates select="@*|node()">
    </xsl:template>
  </xsl:stylesheet>

Note that the apply-templates node is missing a trailing slash. I ran
xalan.exe under the windows debugger, and set a breakpoint after the call to
transform and before the call to getLastError. I specified any old xml file
as source, and this stylesheet as the script. At the breakpoint, the output
window shows this message:

  XSLT warning: Fatal Error at (file test1.xsl, line 5, column 16): Expected
end o
  f tag 'xsl:apply-templates' (test1.xsl, line 5, column 16)

(Note: the column number is incorrect because I changed some tabs to spaces
for the purposes of this email message.) Then I step past the getLastError
statement, and this message gets output.

  Expected end of tag 'xsl:apply-templates'

So getLastError() only returns the the message, without the filename, line
number, or column number. The first message is output someplace inside the
transform() call, I haven't tracked that down.

Not a highly sophisticated debugging scheme, I realize, but it's a way for
you to easily duplicate the problem. :)

Oh, I should mention I'm running the standard 1.4 release, not the interim
2002-10-21 release.

Don


Re: Getting the line and column number of an error

Posted by David N Bertoni/Cambridge/IBM <da...@us.ibm.com>.



Hi Don,

You can set the ProblemListener for the XalanTransformer instance, and most
errors (but not all, unfortunately) will come through the call.  See the
classes ProblemListenerDefault and XalanTransformerProblemListener for more
information.  The purpose of the latter is to allow re-direction of
warnings to a stream specified by the user.

However, since errors which have line number information should have that
information in the string returned by getLastError(), this may be a bug.
Can you describe what sort of error it is?

Dave



                                                                                                                                              
                      "Don McClimans"                                                                                                         
                      <dmcclimans@IntiElect         To:      <xa...@xml.apache.org>                                                   
                      ronics.com>                   cc:      (bcc: David N Bertoni/Cambridge/IBM)                                             
                                                    Subject: Getting the line and column number of an error                                   
                      01/08/2003 08:51 AM                                                                                                     
                                                                                                                                              



I want to show the line and column number any errors that occur during a
transform. Is there an easy way to do this?

I looked at Xalan.exe, which does report this information. But it's not in
the return string from getLastError(), rather,
XalanTransformer::transform()
seems to dump this information to cout or cerr. I guessed that this was
being done by the ProblemListener that is part of a XalanTransformer, but
when I call getProblemListnere(), it returns null.

I've browsed around the API docs for ProblemListener and
XalanTransformerProblemListener, but I haven't groked the "big picture" to
know what I should be using when. It seems like this should be simple, but
I'm confused. Please point me in the right direction! :)

Thanks,

Don McClimans




Re: Getting the line and column number of an error

Posted by David N Bertoni/Cambridge/IBM <da...@us.ibm.com>.



Hi Don,

You can set the ProblemListener for the XalanTransformer instance, and most
errors (but not all, unfortunately) will come through the call.  See the
classes ProblemListenerDefault and XalanTransformerProblemListener for more
information.  The purpose of the latter is to allow re-direction of
warnings to a stream specified by the user.

However, since errors which have line number information should have that
information in the string returned by getLastError(), this may be a bug.
Can you describe what sort of error it is?

Dave



                                                                                                                                              
                      "Don McClimans"                                                                                                         
                      <dmcclimans@IntiElect         To:      <xa...@xml.apache.org>                                                   
                      ronics.com>                   cc:      (bcc: David N Bertoni/Cambridge/IBM)                                             
                                                    Subject: Getting the line and column number of an error                                   
                      01/08/2003 08:51 AM                                                                                                     
                                                                                                                                              



I want to show the line and column number any errors that occur during a
transform. Is there an easy way to do this?

I looked at Xalan.exe, which does report this information. But it's not in
the return string from getLastError(), rather,
XalanTransformer::transform()
seems to dump this information to cout or cerr. I guessed that this was
being done by the ProblemListener that is part of a XalanTransformer, but
when I call getProblemListnere(), it returns null.

I've browsed around the API docs for ProblemListener and
XalanTransformerProblemListener, but I haven't groked the "big picture" to
know what I should be using when. It seems like this should be simple, but
I'm confused. Please point me in the right direction! :)

Thanks,

Don McClimans