Developer

Utilize XML-RPC in Perl

XMLRPC::Lite is a Perl module that takes care of the complex operations of building your XML-RPC requests. Learn how to use XML-RPC in Perl.

This article originally appeared as a Web Development Zone e-newsletter.

By Phillip Perkins

XML-RPC is a spec and a set of implementations that allow software running on disparate operating systems and in different environments to make procedure calls over the Internet.

XML-RPC is designed to be simple to use. In fact, the actual calling mechanism is transported across HTTP. Method names and parameters are wrapped up in XML and passed across HTTP; return values are also wrapped up in XML. Using XML allows for complex data type parameters and return values.

Here's the basic XML-RPC request:

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 212

<?xml version="1.0"?>
<methodCall>
    <methodName>object.methodName</methodName>
        <params>
            <param>
                <value><i4>intValue</i4></value>
            </param>
        </params>
</methodCall>

This information is sent to the host application through the HTTP-POST request. The response comes back via normal HTTP response except the content type is "text/xml", and the response data is in the following format:

<?xml version="1.0"?>
<methodResponse>
    <params>
         <param>
             <value><string>Some string value.</string></value>
         </param>
    </params>
</methodResponse>

You may have noticed that the <value> tag in the request and the response wrap the data in a value type: <i4> and <string>. These tell the server and the client what type of data these values are. For instance, <i4> is a four-byte signed integer, and <string> is a string. You can create arrays and more complex data structures by combinations of data types. You can find more information about this at the XML-RPC.com Web site.

What's great is that someone has already done a lot of work for you. XMLRPC::Lite is a Perl module that takes care of the complex operations of building your XML-RPC requests. One particularly fun XML-RPC provider is the Covers Project. The Covers Project Web site provides a few methods for searching songs covered by other artists and artists that cover songs.

For my example, I'm going to use the covers.Covered() method for returning an array of artists and covered songs. First, I'll create a page for simply entering the original artist's name:

<html>
<body>
<form method="POST" action="getCovers.pl" name="thisForm">
<input type="textbox" name="txtArtist" size=25><br>
<input type="submit" value="Get Covers. . .">
</form>
</body>
</html>

This page is just a text box to enter the artist's name and a submit button to make the request. The Perl code is also pretty simple:

use XMLRPC::Lite;

my $url = 'http://www.coversproject.com:80/RPC.php';

print "Content-type: text/html\n\n";

read(STDIN, my $post, $ENV{'CONTENT_LENGTH'});
my @datas = split(/\&/g, $post);
my $values;
foreach $data (@datas) {
    my ($key, $value) = split(/\=/g, $data);
    $value =~ s/\+/ /g;
    $values{$key} = $value;
}

my @method =
    (
        'covers.Covered',
        (
            XMLRPC::Data->type( string => $values{'txtArtist'}, ),
        )
    );

my $res = XMLRPC::Lite
    -> proxy($url)
#    -> on_debug(sub { print @_; })
    -> call(@method)
    -> result();
    
print <<EOF;
<html>
<body>
<table cellpadding="0" cellspacing="0" border="1">
<thead><th>Artist</th><th>Cover</th></thead>
EOF

my @groups = @{$res};
foreach my $group (@groups) {
    print "<tr><td>" . $group->{'artist'} . "</td><td>" . $group->{'song'} .
"</td></tr>\n";
}

print "</table></body></html>\n";

exit;

This code brings in the XMLRPC::Lite package and then sets a variable for storing the RPC host URL. After reading in and parsing the data from the HTTP-POST, it creates a method structure for the call() method for the XMLRPC::Lite object. In order to pass the correct type of parameter, I use the XMLRPC::Data library to create a string type. The script then makes the call and adds the result to the $res variable. The beginning HTML is printed out, which is nothing more than the HTML and BODY declarations and the TABLE setup.

The $res variable is an anonymous reference to an array of anonymous hashes. I dereference the array and store the array to @groups. I then step through the hash references and print out the 'artist' and 'song' values. The final HTML is printed and the script is exited.

This code is really quite simple. It uses the functionality of a pre-existing service to add functionality to your site. You can also create your own RPC host using the XMLRPC::Lite package. Visit the CPAN Web site to get more information on this and other functionality on the XMLRPC::Lite package.

Phillip Perkins is a contractor with Ajilon Consulting. His experience ranges from machine control and client/server to corporate intranet applications.

Editor's Picks