| XML-Filter-ExceptionLocator documentation | Contained in the XML-Filter-ExceptionLocator distribution. |
XML::Filter::ExceptionLocator - filter to add line/col numbers to SAX errors
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 $@;
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';
Please use rt.cpan.org to report bugs in this module:
http://rt.cpan.org
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
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
Sam Tregar <sam@tregar.com>
Copyright (C) 2004 Sam Tregar
This program is free software; you can redistribute it and/or modify it under the same terms as Perl 5 itself.
| 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__