package XMLRPC::Fast::DecodeWith::XMLTreePP;
use strict;
use warnings;
use MIME::Base64;
use XML::TreePP;
#
# decode_xmlrpc()
# -------------
sub decode_xmlrpc {
my ($xml) = shift;
# parse the XML document
my $tpp = XML::TreePP->new(
force_array => [qw< data member param >],
);
my $tree = $tpp->parse($xml);
my %struct;
# detect the message type, decode the parameters
if ($tree->{methodCall}) {
%struct = (
type => "request",
methodName => $tree->{methodCall}{methodName},
params => [
map decode_value($_->{value}),
@{ $tree->{methodCall}{params}{param} }
],
);
}
elsif ($tree->{methodResponse}) {
if ($tree->{methodResponse}{fault}) {
# this is a fault message
%struct = (
type => "fault",
fault => decode_value($tree->{methodResponse}{fault}),
);
}
else {
# this is a normal response message
%struct = (
type => "response",
params => [
map decode_value($_->{value}),
@{ $tree->{methodResponse}{params}{param} }
],
);
}
}
else {
die "unknown type of message";
}
return \%struct
}
#
# decode_value()
# ------------
sub decode_value {
my ($node) = shift;
return unless defined $node;
my @list = ref $node eq "ARRAY" ? @$node : $node;
my @result;
for my $vnode (@list) {
if ($vnode->{struct}) {
push @result, {
map { $_->{name} => decode_value($_->{value}) }
@{ $vnode->{struct}{member} }
};
}
elsif ($vnode->{array}) {
push @result, [
map decode_value($_->{value}), @{ $vnode->{array}{data} }
];
}
else { # scalar
my ($type, $val) = each %$vnode;
push @result, $type eq "int" ? int $val
: $type eq "i4" ? int $val
: $type eq "boolean"? int $val
: $type eq "double" ? $val / 1.0
: $type eq "base64" ? decode_base64($val)
: $val; # string, datetime
}
}
return @result
}
__PACKAGE__
__END__
=head1 NAME
XMLRPC::Fast::DecodeWith::XMLTreePP - XML-RPC decoder based on XML::TreePP
=head1 DESCRIPTION
This is an alternate decoding function for L<XMLRPC::Fast>, using L<XML::TreePP>
as the XML engine. Based on L<XML::RPC>, heavily simplified. Unsurprisingly,
performs rather poorly when compared to other modules.
=head1 AUTHOR
SE<eacute>bastien Aperghis-Tramoni E<lt>[email protected]<gt>