root/lang/perl/RPC-XML-Parser-LibXML/trunk/lib/RPC/XML/Parser/LibXML.pm @ 9115

Revision 9115, 3.2 kB (checked in by tokuhirom, 5 years ago)

lang/perl/RPC-XML-Parser-LibXML: Checking in changes prior to tagging of version 0.02. Changelog diff is:

=== Changes
==================================================================
--- Changes (revision 11592)
+++ Changes (local)
@@ -1,4 +1,7 @@

Revision history for Perl extension RPC::XML::Parser::LibXML


+0.02
+ - initial cpan release.
+

0.01 Tue Mar 4 11:26:24 2008

  • original version
Line 
1package RPC::XML::Parser::LibXML;
2use strict;
3use warnings;
4use 5.00800;
5our $VERSION = '0.02';
6use base qw/Exporter/;
7use RPC::XML;
8use XML::LibXML;
9use MIME::Base64;
10use Carp;
11
12our @EXPORT = qw/parse_rpc_xml/;
13
14our $TYPE_MAP = +{
15    int                => 'RPC::XML::int',
16    i4                 => 'RPC::XML::int',
17    boolean            => 'RPC::XML::boolean',
18    string             => 'RPC::XML::string',
19    double             => 'RPC::XML::double',
20    'dateTime.iso8601' => 'RPC::XML::datetime_iso8601',
21};
22
23sub parse_rpc_xml {
24    my $xml = shift;
25
26    my $x = XML::LibXML->new;
27    my $doc = $x->parse_string($xml)->documentElement;
28
29    if ($doc->findnodes('/methodCall')) {
30        return RPC::XML::request->new(
31            $doc->findvalue('/methodCall/methodName'),
32            _extract($doc->findnodes('//params/param/value/*'))
33        );
34    } elsif ($doc->findnodes('/methodResponse/params')) {
35        return RPC::XML::response->new(
36            _extract($doc->findnodes('//params/param/value/*'))
37        );
38    } elsif ($doc->findnodes('/methodResponse/fault')) {
39        return RPC::XML::response->new(
40            RPC::XML::fault->new(
41                $doc->findvalue('/methodResponse/fault/value/struct/member/value/int'),
42                $doc->findvalue('/methodResponse/fault/value/struct/member/value/string'),
43            ),
44        );
45    } else {
46        croak "invalid xml: $xml";
47    }
48}
49
50sub _extract {
51    my @nodes = @_;
52
53    my @args;
54
55    for my $node (@nodes) {
56        my $nodename = $node->nodeName;
57        my $val = $node->textContent;
58
59        if ($nodename eq 'base64')  {
60            push @args, RPC::XML::base64->new(decode_base64($val));
61        } elsif ($nodename eq 'struct') {
62            my @members = $node->findnodes('./member'); # XXX
63            my $result = {};
64            for my $member (@members) {
65                my($name)  = $member->findnodes('./name');
66                my($value) = $member->findnodes('./value/*');
67                ($result->{$name->textContent}, ) = _extract($value);
68            }
69            push @args, RPC::XML::struct->new($result);
70        } elsif ($nodename eq 'array') {
71            push @args, RPC::XML::array->new(_extract($node->findnodes($node->nodePath . '/data/value/*')));
72        } else {
73            my $class = $TYPE_MAP->{ $nodename } or next;
74            push @args, $class->new($val);
75        }
76    }
77
78    return @args;
79}
80
811;
82__END__
83
84=encoding utf8
85
86=head1 NAME
87
88RPC::XML::Parser::LibXML - Fast XML-RPC parser with libxml
89
90=head1 SYNOPSIS
91
92    use RPC::XML::Parser::LibXML;
93
94    my $req = parse_rpc_xml(qq{
95      <methodCall>
96        <methodName>foo.bar</methodName>
97        <params>
98          <param><value><string>Hello, world!</string></value></param>
99        </params>
100      </methodCall>
101    });
102    # $req is a RPC::XML::request
103
104=head1 DESCRIPTION
105
106RPC::XML::Parser::LibXML is fast XML-RPC parser written with XML::LibXML.
107
108=head1 AUTHOR
109
110Tokuhiro Matsuno E<lt>tokuhirom AAJKLFJEF GMAIL COME<gt>
111
112Tatsuhiko Miyagawa
113
114=head1 SEE ALSO
115
116L<RPC::XML::Parser>, L<RPC::XML::Parser::XS>, L<XML::LibXML>
117
118=head1 LICENSE
119
120This library is free software; you can redistribute it and/or modify
121it under the same terms as Perl itself.
122
123=cut
Note: See TracBrowser for help on using the browser.