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, using L as the XML engine. Based on L, heavily simplified. Unsurprisingly, performs rather poorly when compared to other modules. =head1 AUTHOR SEbastien Aperghis-Tramoni Esaper@cpan.orgE