#
# Copyright (C) 1998, 1999 Ken MacLeod
# XML::Grove::PerlSAX is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
# $Id: PerlSAX.pm,v 1.3 1999/08/17 15:01:28 kmacleod Exp $
#
use strict;
package XML::Grove::PerlSAX;
use UNIVERSAL;
use Data::Grove::Visitor;
sub new {
my $type = shift;
my $self = ($#_ == 0) ? shift : { @_ };
return bless $self, $type;
}
sub parse {
my $self = shift;
die "XML::Grove::PerlSAX: parser instance ($self) already parsing\n"
if (defined $self->{ParseOptions});
# If there's one arg and it's a subclass of Data::Grove,
# then that's what we're parsing
my $args;
if (scalar (@_) == 1 && UNIVERSAL::isa($_[0], 'Data::Grove')) {
$args = { Source => { Grove => shift } };
} else {
$args = (scalar (@_) == 1) ? shift : { @_ };
}
my $parse_options = { %$self, %$args };
$self->{ParseOptions} = $parse_options;
# ensure that we have at least one source
if (!defined $parse_options->{Source}
|| !(defined $parse_options->{Source}{Grove})) {
die "XML::Grove::PerlSAX: no source defined for parse\n";
}
# assign default Handler to any undefined handlers
if (defined $parse_options->{Handler}) {
$parse_options->{DocumentHandler} = $parse_options->{Handler}
if (!defined $parse_options->{DocumentHandler});
}
# ensure that we have a DocumentHandler
if (!defined $parse_options->{DocumentHandler}) {
die "XML::Grove::PerlSAX: no Handler or DocumentHandler defined for parse\n";
}
# cache DocumentHandler in self for callbacks
$self->{DocumentHandler} = $parse_options->{DocumentHandler};
if (ref($self->{Source}{Grove}) !~ /Document/) {
$self->{DocumentHandler}->start_document( { } );
$parse_options->{Source}{Grove}->accept($self);
return $self->{DocumentHandler}->end_document( { } );
} else {
$self->{Source}{Grove}->accept($self);
}
# clean up parser instance
delete $self->{ParseOptions};
delete $self->{DocumentHandler};
}
sub _parse_self {
my $grove = shift;
my $self = ($#_ == 0) ? shift : { @_ };
bless $self, 'XML::Grove::PerlSAX';
if (ref($grove) !~ /Document/) {
$self->{DocumentHandler}->start_document( { } );
$grove->accept($self);
return $self->{DocumentHandler}->end_document( { } );
} else {
return $grove->accept($self);
}
}
sub visit_document {
my $self = shift; my $grove = shift;
$self->{DocumentHandler}->start_document($grove);
$grove->children_accept($self);
return $self->{DocumentHandler}->end_document($grove);
}
sub visit_element {
my $self = shift; my $element = shift;
$self->{DocumentHandler}->start_element($element);
$element->children_accept($self);
return $self->{DocumentHandler}->end_element($element);
}
sub visit_entity {
my $self = shift; my $entity = shift;
return $self->{DocumentHandler}->int_entity($entity);
}
sub visit_pi {
my $self = shift; my $pi = shift;
return $self->{DocumentHandler}->processing_instruction($pi);
}
sub visit_comment {
my $self = shift; my $comment = shift;
return $self->{DocumentHandler}->comment($comment);
}
sub visit_characters {
my $self = shift; my $characters = shift;
return $self->{DocumentHandler}->characters($characters);
}
package XML::Grove::Document;
sub parse {
goto &XML::Grove::PerlSAX::_parse_self;
}
package XML::Grove::Element;
sub parse {
goto &XML::Grove::PerlSAX::_parse_self;
}
1;
__END__
=head1 NAME
XML::Grove::PerlSAX - an PerlSAX event interface for XML objects
=head1 SYNOPSIS
use XML::Grove::PerlSAX;
$parser = XML::Grove::PerlSAX->new( [OPTIONS] );
$result = $parser->parse( [OPTIONS] );
# or
$result = $xml_object->parse( [OPTIONS] );
=head1 DESCRIPTION
C