Depending on the nature of your request (size, content, how much does the structure depend on the input), there are several different ways to do this.
The most simple way would be to store your request inside a string in your program, put variables in and then send it.
#!/usr/bin/perl
use strict; use warnings;
use LWP::UserAgent;
my ($param1, $param2) = (1, 2);
my $xml = <<XMLREQUEST
<request>
<param1>$param1</param1>
<param2>$param2</param2>
</request>
XMLREQUEST
;
my $ua = LWP::UserAgent->new;
my $response = $ua->post('http://www.yourdomain.com/', Content => $xml);
if ($response->is_success) {
print $response->decoded_content; # or whatever
}
else {
die $response->status_line;
}
In this case, we are using LWP::UserAgent
to do the sending/receiving for us.
The next step would be to use a template engine. Text::Template
can be used to do it. Our sample code with it looks like this:
#!/usr/bin/perl
use strict; use warnings;
use LWP::UserAgent;
use Text::Template;
my $vars = {
'username' => 'jon',
'password' => 'verysecure',
'param1' => {
'content' => 'a lot of content for param1',
'foo' => 'fofofofooo',
},
'param2' => {
'content' => 'even more of content for param2',
'bar' => 'bar bar bar',
},
'param3' => {
'content' => 'some content for param3',
},
};
my $template = Text::Template->new(TYPE => 'FILEHANDLE', SOURCE => \*DATA );
my $xml = $template->fill_in(HASH => $vars);
my $ua = LWP::UserAgent->new;
my $response = $ua->post('http://www.yourdomain.com/', Content => $xml);
if ($response->is_success) {
print $response->decoded_content; # or whatever
}
else {
die $response->status_line;
}
__DATA__
<request>
<auth>
<username>{$username}</username>
<password>{$password}</password>
</auth>
<param1 foo="{$param1{'foo'}}">{$param1{'content'}}</param1>
<param2 bar="{$param2{'bar'}}">{$param2{'content'}}</param2>
<param3>{$param3{'content'}}</param3>
</request>
It takes the $vars
hashref and puts its content at the respective places in the template. $var->{'username'}
is filled in at where the template says {$username}
. The template in this case is read from the DATA
section, which is specified below the program. A good way would be to have a template file for each request type you need to do. If the request contains optional elements, Text::Template
can take care of this with conditional statements (putting Perl code in the template).
If you prefer a more dynamic approach, consider XML::Simple
for easy tasks. Keep in mind that XML::Simple
is not the best XML module around. There are others, like XML::Twig
, that are more robust.
#!/usr/bin/perl
use strict; use warnings;
use LWP::UserAgent;
use XML::Simple;
my $xmlHash = {
'request' => {
'auth' => [
{
'username' => 'jon',
},
{
'password' => 'verysecure',
},
],
'param1' => {
'content' => 'a lot of content for param1',
'foo' => 'fofofofooo',
},
'param2' => {
'content' => 'even more of content for param2',
'bar' => 'bar bar bar',
},
'param3' => {
'content' => 'some content for param3',
},
}
};
my $xml = XMLout($xmlHash, KeepRoot => 1);
my $ua = LWP::UserAgent->new;
my $response = $ua->post('http://www.yourdomain.com/', Content => $xml);
if ($response->is_success) {
print $response->decoded_content; # or whatever
}
else {
die $response->status_line;
}
You should read through the docs of XML::Simple
because it is a bit strange sometimes.
If you want to parse the reply of your request which is also XML then XML::Simple
can also be used for that. The XMLin()
does the trick here.
If you have a very complicated web service that you want to implement, taking a look at SOAP::Lite
or (if you have a large WSDL file) SOAP::WSDL
.