XML::Filter::ExceptionLocator - filter to add line/col numbers to SAX errors


XML-Filter-ExceptionLocator documentation Contained in the XML-Filter-ExceptionLocator distribution.

Index


Code Index:

NAME

Top

XML::Filter::ExceptionLocator - filter to add line/col numbers to SAX errors

SYNOPSIS

Top

  use XML::Filter::ExceptionLocator;
  use XML::SAX::ParserFactory;

  # parse some.xml adding line/col numbers to any errors that get
  # thrown from $whatever
  my $filter = XML::Filter::ExceptionLocator->new(Handler => $whatever);
  my $parser = XML::SAX::ParserFactory->parser(Handler => $filter);
  eval { $parser->parse_uri('some.xml'); }

  # the error object will have LineNumber and ColumnNumber now
  if ($@ and ref $@ and $@->isa('XML::SAX::Exception')) {
     print "Your error is at line $@->{LineNumber}, col $@->{ColumnNumber}\n";
  }

  # if you print the error the line and column are included
  print $@;

DESCRIPTION

Top

This module implements a SAX filter which adds line-numbers and column-numbers to errors generated by SAX handlers futher down the pipeline. I wrote this module so that XML::Validator::Schema could blame the correct line of XML for validation failures.

NOTE: This module requires a SAX parser which correctly supports the set_document_locator() call. At present there is just one, XML::SAX::ExpatXS. If you've got a number of XML::SAX parsers installed and you want to make sure XML::SAX::ExpatXS is used, do this:

   $XML::SAX::ParserPackage = 'XML::SAX::ExpatXS';

BUGS

Top

Please use rt.cpan.org to report bugs in this module:

  http://rt.cpan.org

SUPPORT

Top

This module is supported on the perl-xml mailing-list. Please join the list if you have questions, suggestions or patches:

  http://listserv.activestate.com/mailman/listinfo/perl-xml

CVS

Top

If you'd like to help develop this module you'll want to check out a copy of the CVS tree:

  http://sourceforge.net/cvs/?group_id=89764

AUTHOR

Top

Sam Tregar <sam@tregar.com>

COPYRIGHT AND LICENSE

Top

SEE ALSO

Top

XML::Validator::Schema


XML-Filter-ExceptionLocator documentation Contained in the XML-Filter-ExceptionLocator distribution.

package XML::Filter::ExceptionLocator;
use 5.006;
use strict;
use warnings;
our $VERSION = '1.00';

use base 'XML::SAX::Base';

# from XML::Filter::XInclude
sub set_document_locator {
    my ($self, $locator) = @_;
    push @{$self->{locators} ||= []}, $locator;
    
    $self->SUPER::set_document_locator($locator);
}

# install handler for all SAX methods
BEGIN {
    for my $method qw(start_document     end_document           start_element
                      end_element        processing_instruction comment
                      skipped_entity     ignorable_whitespace   end_entity
                      start_entity       entity_reference
                      start_cdata        end_cdata) {
        no strict 'refs';
        my $super_meth = "SUPER::$method";
        *{__PACKAGE__ . "::$method"} = 
          sub { 
              my $self = shift;

              # call method in expected context
              my $wantarray = wantarray;
              my (@ret, $ret);
              if ($wantarray) {
                  eval { @ret = $self->$super_meth(@_); };
              } else {
                  eval { $ret = $self->$super_meth(@_); };
              }

              # handle errors
              my $err = $@;
              if ($err and ref($err) and $err->isa('XML::SAX::Exception')) {
                  # it's showtime, add in Line/Col
                  if ($self->{locators} and @{$self->{locators}}) {
                      $err->{LineNumber}   = $self->{locators}[-1]->{LineNumber};
                      $err->{ColumnNumber} = $self->{locators}[-1]->{ColumnNumber};
                  }
                  die $err;
              } elsif ($err) {
                  die $err;
              }

              return @ret if $wantarray;
              return $ret;
          }
      }
}             

1;
__END__