Catmandu-XML
view release on metacpan or search on metacpan
lib/Catmandu/XML/Transformer.pm view on Meta::CPAN
package Catmandu::XML::Transformer;
our $VERSION = '0.17';
use Catmandu::Sane;
use Moo;
use Carp;
use XML::LibXML;
use XML::LibXSLT;
use Scalar::Util qw(blessed reftype);
use XML::Struct::Reader;
use XML::Struct::Writer;
has stylesheet => (
is => 'ro',
coerce => sub {
ref $_[0] // '' eq 'ARRAY' ? $_[0] : [ split /,/, $_[0] ]
},
default => sub { [] }
);
has output_format => (
is => 'ro',
coerce => sub { defined $_[0] ? lc $_[0] : undef }
);
has process => (
is => 'lazy',
builder => sub {
[
map {
XML::LibXSLT->new()->parse_stylesheet(
XML::LibXML->load_xml(location => $_, no_cdata=>1)
)
} @{$_[0]->stylesheet}
]
}
);
sub BUILD {
if (@{$_[0]->process} and $_[0]->process->[-1]->output_method eq 'text') {
$_[0]->{output_format} = 'string';
}
}
sub transform {
my ($self, $xml) = @_;
my ($format, $result);
return if !defined $xml;
if (blessed $xml) {
if ($xml->isa('XML::LibXML::Document') or $xml->isa('XML::LibXML::Element')) {
$format = 'dom';
} else {
croak "Cannot convert ".ref($xml)." to XML";
}
} elsif (ref $xml) {
if (reftype $xml eq 'ARRAY') {
$format = 'struct';
$xml = XML::Struct::Writer->new->write($xml);
} else {
$format = 'simple';
$xml = XML::Struct::Writer->new(simple => 1)->write($xml);
}
} else {
$format = 'string';
$xml = XML::LibXML->load_xml(string => $xml);
}
$format = $self->output_format if $self->output_format;
if (@{$self->process}) {
foreach (@{$self->process}) {
$xml = $_->transform($xml);
}
}
if ($format eq 'string') {
if ($self->process->[-1]) {
return $self->process->[-1]->output_as_chars($xml);
} else {
return $xml->toString;
}
} elsif ($format eq 'struct') {
return XML::Struct::Reader->new( from => $xml )->readDocument;
} elsif ($format eq 'simple') {
my $reader = XML::Struct::Reader->new( from => $xml, simple => 1, root => 1 );
return $reader->readDocument;
} else {
return $xml;
}
}
( run in 0.656 second using v1.01-cache-2.11-cpan-5a3173703d6 )