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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.