XML-Toolkit
view release on metacpan or search on metacpan
lib/XML/Toolkit/Generator/Default.pm view on Meta::CPAN
package XML::Toolkit::Generator::Default;
{
$XML::Toolkit::Generator::Default::VERSION = '0.15';
}
use Moose;
use Encode;
use namespace::autoclean;
extends qw(XML::Generator::Moose);
with qw(
XML::Toolkit::Generator::Interface
XML::Toolkit::Builder::NamespaceRegistry
);
after 'xml_decl' => sub {
my $self = shift;
for my $pair ( $self->xmlns_pairs ) {
my ( $prefix, $uri ) = @$pair;
$self->start_prefix_mapping( $prefix => $uri, );
}
$self->newline;
};
sub get_element_name {
my ( $self, $meta ) = @_;
if ( $meta->can('description') ) {
return $meta->description->{Name};
}
else {
my $name = $meta->name;
$name =~ /::(\w+)$/oi;
return lcfirst $1;
}
}
sub is_node {
my ( $self, $attr ) = @_;
confess "no attribute" unless $attr;
return 0 unless $attr->can('description');
return 0 unless $attr->description->{node_type};
return 1;
}
sub is_child_node {
my ( $self, $attr ) = @_;
return 0 unless $self->is_node($attr);
return 1 if $attr->description->{node_type} eq 'child';
return 0;
}
sub is_text_node {
my ( $self, $attr ) = @_;
return 0 unless $self->is_node($attr);
return 1 if $attr->description->{node_type} eq 'character';
return 0;
}
sub is_cdata_node {
my ( $self, $attr ) = @_;
return 0 unless $self->is_node($attr);
return 1 if $attr->description->{cdata};
return 0;
}
sub is_attribute_node {
my ( $self, $attr ) = @_;
return 0 unless $self->is_node($attr);
return 1 if $attr->description->{node_type} eq 'attribute';
return 0;
}
sub get_attribute_nodes {
my ( $self, $meta, $obj ) = @_;
my @attrs = grep { $self->is_attribute_node($_) }
grep { defined $_->get_value($obj) }
map { $meta->get_attribute($_) } $meta->get_attribute_list;
return map {
$_->description->{LocalName} =>
{ %{ $_->description }, Value => $_->get_value($obj) }
} @attrs;
}
sub parse_object {
my ( $self, $meta, $obj, $descr ) = @_;
my %attrs = $self->get_attribute_nodes( $meta, $obj );
my $name = $descr->{Name};
$self->start_element(
$name => \%attrs,
$descr,
);
for my $attr ( $self->_get_sorted_filtered_attributes($meta) ) {
if ( $self->is_text_node($attr) ) {
my $data = $attr->get_value($obj);
$self->is_cdata_node($attr)
? $self->cdata($data)
: $self->characters($data);
}
elsif ( $self->is_child_node($attr) ) {
next unless my $value = $attr->get_value($obj);
for my $child ( grep { defined } @$value ) {
next unless blessed $child;
$self->parse_object( $child->meta, $child, $attr->description );
}
}
else { warn "${\$attr->dump} is funky" }
}
$self->end_element($name);
}
augment 'parse' => sub {
my ( $self, $obj ) = @_;
$self->parse_object( $obj->meta, $obj, { Name => $self->get_element_name( $obj->meta ) } );
};
sub _get_sorted_filtered_attributes {
my ( $self, $meta ) = @_;
sort {
return -1 unless exists $a->description->{sort_order};
return 1 unless exists $b->description->{sort_order};
return $a->description->{sort_order} <=> $b->description->{sort_order}
}
grep { !$self->is_attribute_node($_) }
grep { !$_->does('XML::Toolkit::Trait::NoXML') }
$meta->get_all_attributes;
}
__PACKAGE__->meta->make_immutable;
1;
__END__
=head1 NAME
XML::Toolkit::Generator::Default - A Default Moose Object to XML Generator
=head1 VERSION
version 0.15
=head1 SYNOPSIS
use XML::Toolkit::Generator::Default;
XML::Toolkit::Generator::Default->new( Handler => XML::SAX::Writer->new );
=head1 DESCRIPTION
A subclass of XML::Generator::Moose, this class generates SAX events from
Moose objects.
=head1 ATTRIBUTES
See XML::Generator::Moose.
=head1 METHODS
( run in 0.747 second using v1.01-cache-2.11-cpan-39bf76dae61 )