Re: Shortcutting a SAX parser
Michael Ludwig <[email protected]>
| Newsgroups | gmane.comp.lang.perl.xml |
|---|---|
| Message-ID | <[email protected]> |
Robin Berjon schrieb:
> On Mar 31, 2009, at 06:33 , Michael Ludwig wrote:
>> Is dying the way to go here? Or is there a more elegant and
>> recommended way to terminate the parser? Other thoughts or comments?
>
> Yes, you guessed right (in fact it's documented in
> http://perl-xml.sourceforge.net/perl-sax/ but I can't get you the
> exact pointer as my hotel connection is horridly slow), that's a
> perfectly valid approach.
Hi Robin,
thanks for answering! Here's the exact link, and the perldoc:
http://perl-xml.sourceforge.net/perl-sax/sax-2.1.html#Exceptions
perldoc XML::SAX::Exception
> If you want to be absolutely strict and defensive in your programming,
> you probably want to throw a specific exception (SAX exceptions are
> expected to have at least a Message key with a reason for throwing)
> and check that that's the one you're getting. That way, if your
> document does turn out to have a problem, your code won't confuse
> "threw because I got what I wanted" with "threw because something
> smells bad".
That's true, of course you really should do that. However, two things
combine to make this difficult.
First, after a die(), the $@ variable also contains (from the point of
view of the program logic) random line number information, which, in a
hackerish manner, you'd then have to weed out in order to compare the
string to the expected one.
eval { die 'Gurke' };
print $@ if $@;
That's not pretty. There must be a better way.
Second, the documentation I referred to above does not describe the
behaviour I'm observing. $@ is not a blessed hash reference, but a
simple string. Maybe that has to do with the fact that the class
overloads "", but then, I don't know how to get at the object. See
test case below.
Michael Ludwig
milu@colinux:~/ds > expand -t2 chax.pl
#!/usr/bin/perl
# [comments snipped]
package MySAXHandler;
use strict;
use warnings;
use base 'XML::SAX::Base';
@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 => 'Doc done' );
}
}
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 XML::SAX;
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";
};
my %handler_opt = (
# elm_searched => 'Gurke',
callback => $callback,
);
my $handler = MySAXHandler->new( %handler_opt);
my $parser = XML::SAX::ParserFactory->parser( Handler => $handler);
while ( <> ) {
chomp;
eval { $parser->parse_uri( $_) };
print Dumper $@ if $@;
}
milu@colinux:~/ds > cat tv.xml
<TVChannel TVChannelID="99" TVChannelName="ARD">
<Moin>Moin</Moin>
</TVChannel>
milu@colinux:~/ds > ls tv.xml | chax.pl
99 ARD
$VAR1 = 'Doc done at /usr/local/lib/perl/5.8.8/XML/LibXML/SAX.pm line 73
at /home/milu/ds/chax.pl line 61
';
_______________________________________________
Perl-XML mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs