XML::RAI::Object - A base class for RAI element objects.
# Copyright (c) 2004-2009 Timothy Appnel
# http://appnel.com/
# This code is released under the Artistic License.
#
# XML::RAI::Object - A base class for RAI element objects.
#
package XML::RAI::Object;
use strict;
use Date::Parse 2.26;
use Date::Format 2.22;
use Scalar::Util qw(weaken);
sub new {
my $class = shift;
my $self = bless {}, $class;
$self->init(@_);
$self;
}
sub init {
$_[0]->{__source} = $_[1];
$_[0]->{__parent} = $_[2];
$_[0]->{__RAI} = $_[2];
while ($_[0]->{__RAI}->can('parent')) {
$_[0]->{__RAI} = $_[0]->{__RAI}->parent;
}
weaken($_[0]->{__parent});
weaken($_[0]->{__RAI});
}
sub src { $_[0]->{__source} }
sub parent { $_[0]->{__parent} }
sub add_mapping {
my ($class, $var, @maps) = @_;
no strict 'refs';
${"${class}::XMap"}->{$var} = []
unless (exists ${"${class}::XMap"}->{$var});
push @{${"${class}::XMap"}->{$var}}, @maps;
}
sub generic_handler {
my ($this, $class, $var) = @_;
no strict 'refs';
foreach (@{${$class . '::XMap'}->{$var}}) {
my @nodes = $this->src->query($_);
if (defined($nodes[0])) {
@nodes = map {
!ref($_) ? $_
: substr($_->name, 0, 30) eq
'{http://www.w3.org/1999/xhtml}' ? join '',
map { as_xhtml($_) } @{$_->contents}
: $_->text_content;
} @nodes;
return wantarray ? @nodes : $nodes[0];
}
}
return undef;
}
sub time_handler {
my @r = generic_handler(@_);
return undef unless $r[0];
my $timef = $_[0]->{__RAI}->time_format;
if ($timef eq 'EPOCH') {
map { $_ = str2time($_, 0) } @r;
}
elsif ($timef) {
map { $_ = time2str($timef, str2time($_, 0), 0) } @r;
}
wantarray ? @r : $r[0];
}
use XML::RSS::Parser::Util qw(as_xml);
sub as_xhtml { # a hack to get xhtml content as we'd expect.
my $xml = as_xml($_[0]);
$xml =~ s{<(/?)xhtml:}{<$1}g;
$xml;
}
sub DESTROY { }
use vars qw( $AUTOLOAD );
sub AUTOLOAD {
(my $var = $AUTOLOAD) =~ s!.+::!!;
(my $class = $AUTOLOAD) =~ s!::[^:]+$!!;
no strict 'refs';
die "$var is not a recognized method."
unless (${$class . '::XMap'}->{$var});
if ($var =~ m/^(created|modified|issued|valid)(_strict)?$/) {
*$AUTOLOAD = sub { time_handler($_[0], $class, $var) };
}
else {
*$AUTOLOAD = sub { generic_handler($_[0], $class, $var) };
}
goto &$AUTOLOAD;
}
1;
__END__