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
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.