Re: Shortcutting a SAX parser
Michael Ludwig <[email protected]>
| Newsgroups | gmane.comp.lang.perl.xml |
|---|---|
| Message-ID | <[email protected]> |
Robin Berjon schrieb:
> On Apr 8, 2009, at 13:34 , Michael Ludwig wrote:
>> Robin Berjon schrieb:
>>> On Apr 8, 2009, at 11:14 , Michael Ludwig wrote:
>>>>> If it doesn't for you, someone must be catching and rethrowing the
>>>>> exception and stringifying it along the way.
> One (tenuous) lead is that start_element is eventually called by
> XML::LibXML somewhere up the stack, and that's XS, which on occasion
> can lead to surprises. Can you try running the same code with
> XML::SAX::PurePerl?
Bingo, that makes a difference! Using the PurePerl parser, no error
message stringification occurs. See below. Here's the code, in case
anyone wants to inspect this. If you use confess() with the string
argument instead of confess {hash=>'ref'} or throw Ex::Ception, you'll
get a stack trace.
#!/usr/bin/perl
my $EXCEPTION = 'FERTIG';
package MySAXHandler;
use strict;
use warnings;
use base 'XML::SAX::Base';
use Carp;
@XML::SAX::Exception::Done::ISA = ('XML::SAX::Exception');
sub start_element {
my( $self, $elm) = @_;
if ( $elm->{LocalName} eq $self->{elm_searched} ) {
$self->{callback}->( $elm);
throw XML::SAX::Exception::Done( Message => $EXCEPTION);
# confess { Message => $EXCEPTION };
# confess $EXCEPTION;
}
}
sub new {
my( $pkg, %opt) = @_;
my $self = $pkg->SUPER::new( %opt);
$self->{elm_searched} ||= 'TVChannel'; # TVChannel Broadcast
return bless $self, $pkg;
}
# Hauptprogramm --------------------------------------------------------
package main;
use strict;
use warnings;
use Getopt::Std;
use XML::SAX::PurePerl;
use Data::Dumper;
my $callback = sub {
my $elm = shift;
my $att_id = $elm->{Attributes}{'{}TVChannelID'};
my $att_name = $elm->{Attributes}{'{}TVChannelName'};
print $att_id->{Value}, "\t", $att_name->{Value}, "\n";
};
getopts( 'P', \my %opt);
my $usePurePerlParser = $opt{P};
my %handler_opt = (
# elm_searched => 'Gurke',
callback => $callback,
);
my $handler = MySAXHandler->new( %handler_opt);
my $parser = $usePurePerlParser ?
XML::SAX::PurePerl->new( Handler => $handler) :
XML::SAX::ParserFactory->parser( Handler => $handler) ;
while ( <> ) {
chomp;
eval { $parser->parse_uri( $_) };
if ( $@ ) {
print STDERR Dumper $@;
# Irgendetwas stringifiziert die Meldung. Daher substr erforderlich.
# my $ex = substr $@, 0, length $EXCEPTION;
# die $@ if $ex ne $EXCEPTION;
}
}
Input documents look like this:
<TVChannel TVChannelID="71" TVChannelName="ARD">
<Moin>Moin</Moin>
</TVChannel>
Invocation like this:
milu@colinux:~/ds > ls tvARD.xml tvZDF.xml | chax.pl
71 ARD
$VAR1 = 'FERTIG at /usr/local/lib/perl/5.8.8/XML/LibXML/SAX.pm line 73
at /home/milu/ds/chax.pl line 72
';
37 ZDF
$VAR1 = 'FERTIG at /usr/local/lib/perl/5.8.8/XML/LibXML/SAX.pm line 73
at /home/milu/ds/chax.pl line 72
';
milu@colinux:~/ds > ls tvARD.xml tvZDF.xml | chax.pl -P
71 ARD
$VAR1 = bless( {
'Message' => 'FERTIG'
}, 'XML::SAX::Exception::Done' );
37 ZDF
$VAR1 = bless( {
'Message' => 'FERTIG'
}, 'XML::SAX::Exception::Done' );
Michael Ludwig
_______________________________________________
Perl-XML mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs