package Simple::SAX::Serializer;
use warnings;
use strict;
use vars qw($VERSION);
$VERSION = 0.02;
use Abstract::Meta::Class ':all';
use base 'XML::SAX::Base';
use Carp 'confess';
use Simple::SAX::Serializer::Parser;
use XML::SAX;
BEGIN {
eval {
require XML::LibXML;
};
$XML::SAX::ParserPackage = "XML::LibXML::SAX" unless $@;
}
=head1 NAME
Simple::SAX::Serializer - Simple XML serializer
=head1 DESCRIPTION
Represents xml serializer class,
=head1 SYNOPSIS
use Simple::SAX::Serializer;
my $xml = Simple::SAX::Serializer;
$xml->handler('root/child', sub {
my ($self, $element, $parent) = @_;
my $attributes = $element->attributes;
my $result = $parent->children_array_result;
push @$result,Child->new(%$attributes);
});
$xml->handler('root', sub {
my ($self, $element) = @_;
$element->validate_attributes(['dummy'], {attr2 => 'default_value'});
Root->new(%{$element->attributes}, children => $element->children_result);
});
my $xml_content = "<?xml version="1.0"?><root dummy="1"><child id="1" ><child id="2" ></root>";
$xml->parse_string($xml_content);
# or $xml->parse_file ...
=cut
=head2 ATTRIBUTES
=over
=item handlers
=cut
has '%.handlers' => (item_accessor => 'handler');
=back
=head2 METHODS
=over
=item parse_sting
Runs the parser and returns result, xml as string
=cut
sub parse_string {
my $self = shift;
$self->parse('string', @_);
}
=item parse_file
Runs the parser and returns result, xml as file
=cut
sub parse_file {
my ($self, $file) = @_;
$self->parse('file', $file);
}
=item parse
Runs the parser and returns result
=cut
sub parse {
my ($self, $input_type, $xml) = @_;
my $parse_method = "parse_$input_type";
my $handler = Simple::SAX::Serializer::Parser->new;
$handler->{parser} = $self;
my $parser = XML::SAX::ParserFactory->parser(Handler => $handler);
if($input_type eq 'file') {
die "file $xml doesn't exists" unless -e $xml;
}
$parser->$parse_method($xml);
$handler->{result};
}
=item find_handlder
Finds handler for current element.
It start matching from root/element/searched_element
and if not find that it try to resolve by
element/searched_element
and eventually searched_element
If handler is not found then generates an error.
=cut
sub find_handlder {
my ($self, $elements) = @_;
my @path = element_path($elements);
my $handlers = $self->handlers;
my $handler;
for (my $i = 0; $i <= $#path; $i++) {
my $path = join '/', @path[$i .. $#path ];
$handler = $handlers->{$path};
last if $handler;
}
$handler = $handlers->{'*'}
unless $handler;
confess "missing handler for " . join('/', @path)
unless $handler;
$handler;
}
=item element_path
Takes array reference of the elements data structures, return list of element name.
=cut
sub element_path {
my ($elemets) = @_;
map { $_->[0] } @$elemets;
}
1;
__END__
=back
=head1 COPYRIGHT
The Simple::SAX::Serializer module is free software. You may distribute under the terms of
either the GNU General Public License or the Artistic License, as specified in
the Perl README file.
=head1 SEE ALSO
L<Simple::SAX::Serializer::Parser>
L<XML::LibXML::SAX>
=head1 AUTHOR
Adrian Witas, adrian@webapp.strefa.pl
See also
=cut