# $Id: SAX1toSAX2.pm,v 1.4 2002/07/08 11:56:04 matt Exp $
package XML::Filter::SAX1toSAX2;
use strict;
use vars qw($VERSION @ISA);
use XML::SAX::Base;
use XML::NamespaceSupport;
@ISA = qw(XML::SAX::Base);
$VERSION = '0.03';
sub start_document {
my ($self, $document) = @_;
$self->{NSSupport} = XML::NamespaceSupport->new({ xmlns => 1 });
$self->SUPER::start_document($document);
}
sub start_element {
my ($self, $element) = @_;
$self->{NSSupport}->push_context;
$self->make_sax2_attribs($element);
foreach my $prefix ($self->{NSSupport}->get_declared_prefixes) {
# warn("start_prefix_mapping: $prefix\n");
$self->SUPER::start_prefix_mapping(
{
Prefix => $prefix,
NamespaceURI => $self->{NSSupport}->get_uri($prefix),
}
);
}
my ($uri, $prefix, $lname) = $self->{NSSupport}->process_element_name($element->{Name});
$element->{LocalName} = $lname;
$element->{Prefix} = $prefix;
$element->{NamespaceURI} = $uri;
$self->SUPER::start_element($element);
}
sub end_element {
my ($self, $element) = @_;
foreach my $prefix ($self->{NSSupport}->get_declared_prefixes) {
# warn("end_prefix_mapping: $prefix\n");
$self->SUPER::end_prefix_mapping(
{
Prefix => $prefix,
NamespaceURI => $self->{NSSupport}->get_uri($prefix),
}
);
}
delete($self->{Attributes}); # just in case
my ($uri, $prefix, $lname) = $self->{NSSupport}->process_element_name($element->{Name});
# warn("$element->{Name} => $uri, $lname, $prefix\n");
$element->{LocalName} = $lname;
$element->{Prefix} = $prefix;
$element->{NamespaceURI} = $uri;
$self->{NSSupport}->pop_context;
$self->SUPER::end_element($element);
}
sub make_sax2_attribs {
my $self = shift;
my $element = shift;
$self->_scan_namespaces(%{$element->{Attributes}});
my %attribs;
foreach my $key (keys %{$element->{Attributes}}) {
my ($uri, $prefix, $lname) = $self->{NSSupport}->process_attribute_name($key);
$attribs{"{$uri}$lname"} = {
Name => $key,
Value => $element->{Attributes}{$key},
Prefix => $prefix,
NamespaceURI => $uri,
LocalName => $lname,
};
}
$element->{Attributes} = \%attribs;
}
sub _scan_namespaces {
my ($self, %attributes) = @_;
while (my ($attr_name, $value) = each %attributes) {
if ($attr_name =~ /^xmlns(:(.*))?$/) {
my $prefix = $2 || '';
# warn("declare_prefix: $prefix = $value\n");
$self->{NSSupport}->declare_prefix($prefix, $value)
}
}
}
1;
__END__
=head1 NAME
XML::Filter::SAX1toSAX2 - Convert SAX1 events to SAX2
=head1 SYNOPSIS
use XML::Filter::SAX1toSAX2;
# create a SAX2 handler
my $handler = XML::Handler::AxPoint->new();
# filter from SAX1 to SAX2
my $filter = XML::Filter::SAX1toSAX2->new(Handler => $handler);
# SAX1 parser
my $parser = XML::Parser::PerlSAX->new(Handler => $filter);
# parse file
$parser->parse(Source => { SystemId => "file.xml" });
=head1 DESCRIPTION
This module is a very simple module for creating SAX2 events from
SAX1 events. It is useful in the case where you have a SAX1 parser
but want to use a SAX2 handler or filter of some sort.
As an added bonus, it also does namespace processing for you!
=head1 AUTHOR
Matt Sergeant, matt@sergeant.org
=head1 SEE ALSO
XML::Parser::PerlSAX, XML::SAX::Base, XML::Filter::SAX2toSAX1
=cut