Example 3-2. Perl/cgi SOAP client using SOAP::Lite.
I cover here the case of a client accessing a .NET document/literal web service. The other operation style are more easy to consume, and there is a lot of documentation on the internet, and probably of best quality than mine... ;-)
#!/usr/bin/perl -w
# infobelclient.cgi SOAP client for Infobel web service
use strict;
use SOAP::Lite;
print "Content-type: text/html\n\n";
print "<html><head><title>Perl Infobel web service client</title>
<META HTTP-EQUIV='Content-Type' CONTENT=\"text/html; charset=iso-8859-1\">
</head><body>";
print "<h3>Perl client for the .NET Infobel web service using SOAP::Lite</h3>";
# do not forget to specify the soapaction (on_action),
# you will find it in the wsdl.
# uri is the target namespace in the wsdl
# proxy is the endpoint address
my $soap = SOAP::Lite
-> uri('http://www.infobel.com/WebService/')
-> on_action( sub { return '"http://www.infobel.com/WebService/Search"' } )
-> proxy('http://hal.kapitol.com/infobelservices/service1.asmx');
# you must define the namespace used
# in the wsdl, as an attribute to the
# method Search without namespace prefix
# for compatibility with .NET (document/literal)
my $method = SOAP::Data->name('Search')
->attr({xmlns => 'http://www.infobel.com/WebService/'});
# the big part now, refer to the doc on-line of
# the .NET web service. This is very usefull
# to make the query
# You have to construct the following xml structure:
# <inputQuery>
# <login>...</login>
# <password>...</password>
# ....
# <CoordType>...</CoordType>
# </inputQuery>
# Use the constant enumeration as required for
# the fields "country", "service", etc...
# Again refer to the doc of the web service on-line.
my $query =
SOAP::Data
->name(inputQuery =>
\SOAP::Data->value(
SOAP::Data->name(login => 'infobel'),
SOAP::Data->name(password => 'test'),
SOAP::Data->name(country => 'aeCountryBE'),
SOAP::Data->name(service => 'aeSrvStandard'),
SOAP::Data->name(Name => 'durand'),
#SOAP::Data->name(FirstName => ''),
#SOAP::Data->name(Street => ""),
#SOAP::Data->name(bldnum => ""),
SOAP::Data->name(City => 'bruxelles'),
SOAP::Data->name(Zip => ''),
#SOAP::Data->name(Phone => ''),
#SOAP::Data->name(Area => ''),
#SOAP::Data->name(Category => ''),
SOAP::Data->name(XCoord => 0),
SOAP::Data->name(YCoord => 0),
SOAP::Data->name(Range => 0),
SOAP::Data->name(PageStep => 5),
SOAP::Data->name(Language => 'aeLangFrench'),
SOAP::Data->name(CoordType => 'aeCTWGS')));
# make the call
my $result = $soap->call($method => $query);
# if no error
unless ($result->fault) {
# refer to the structure of the xml soap response of
# the web service (use TcpTunnelGui for example) for the
# access of the "status", "numrecs", ... values
my $statusmes = $result->valueof('//SearchResponse/SearchResult/Status');
my $numrecs = $result->valueof('//SearchResponse/SearchResult/Result/NumRecs');
# @crecords will contain the structure of the CRecord object
# containing themselves the fields "name", "address", etc...
# and eventually the structure of category
my @crecords = $result->valueof('//SearchResponse/SearchResult/Result/collRecord/CRecord');
print "<p>message: " . $statusmes;
print "<br>numrecs: $numrecs";
print "<p>record(s):";
my $collcat;
my @cat;
# you can use a foreach loop to access the values
# of each record
foreach my $pcval (@crecords) {
print "<table border=1 width=300>";
print "<tr><td>Name</td><td>".$pcval->{'Name'}."</td></tr>";
print "<tr><td>Address</td><td>".$pcval->{'Address'}."</td></tr>";
print "<tr><td>City</td><td>".$pcval->{'City'}."</td></tr>";
print "<tr><td>Zip</td><td>".$pcval->{'Zip'}."</td></tr>";
print "<tr><td>Phone</td><td>".$pcval->{'Phone'}."</td></tr>";
print "<tr><td>Fax</td><td>".$pcval->{'Fax'}."</td></tr>";
# do the same to access the values nested
# in the array of category
$collcat = $pcval->{'collCategory'};
@cat = $collcat->{'CCategory'};
print "<tr><td>category</td><td><table>";
foreach my $catval (@cat) {
print "<tr><td>".$catval->{'code'}."</td><td>".$catval->{'description'}."</td></tr>";
}
print "</table></td></tr>";
print "<tr><td>Coordinates</td><td>".$pcval->{'XCoord'}.", ".$pcval->{'YCoord'}."</td></tr>";
print "</table><p>";
}
} else {
# some error handling
print join ', ',
$result->faultcode,
$result->faultstring,
$result->faultdetail;
}
print "</body></html>";