0

Being new to Perl and XML..Can any one guide me in order to do the following: I have to write a Perl Code which should do :

  1. Make a connection.

  2. Get the reponse of the connection which is connectionId and store that if in a variable.

  3. Close connection

Input :

XML Request should be posted.The request type is http.

The Syntax of XML I am having along with me.

Can any one guide me what steps I should follow to meet above requirement.

Thanks in advance

Adding the Code:

use LWP::UserAgent;
use HTTP::Request::Common;
# The xml_request
my $xml_req = "<?xml version=1.0 encoding UTF-8?>
            <!ELEMENT drl (openconnection)>
            <!ATTLIST drl
             mode normal
             connectionid null
            >
            <!ELEMENT openconnection EMPTY>
            <!ATTLIST openconnection
            username admin
            password admin
            ></drl>";
my $ua = LWP::UserAgent->new();
my $response = $ua->post("http://XX.X.X.X:XXXX/lab/v1_2/connection/openConnectionRequest.dtd", Content => $xml_req);

The output is a hash but if it should return and id which is a no..where I am going wrong?

user1522786
  • 11
  • 1
  • 3
  • 1
    Use [LWP::UserAgent](http://search.cpan.org/~gaas/libwww-perl-6.04/lib/LWP/UserAgent.pm) to make HTTP requests. The documentation is very thorough. – friedo Jul 13 '12 at 07:10
  • 1
    It helps if you show what you have tried so far and where specificly you have had problems. – matthias krull Jul 13 '12 at 07:31
  • 1
    Welcome to SO. Maybe you should read http://stackoverflow.com/questions/how-to-ask as before asking a question. – dgw Jul 13 '12 at 07:32
  • I've posted a short guide below. Please take @dgw's suggestion into consideration for future questions. – simbabque Jul 13 '12 at 07:53

1 Answers1

1

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.

simbabque
  • 53,749
  • 8
  • 73
  • 136
  • I'd like some constructive criticism on that downvote, please. – simbabque Jul 13 '12 at 09:34
  • I have added the code ..This returns response as HTTP: HTTP::Response=HASH(0x1c6c3600) How to get the actual response..I mean how to decode the content from the above response? – user1522786 Jul 16 '12 at 06:51
  • Which one have you used? `HTTP::Response=HASH(0x1c6c3600)` means that you have an object of the [`HTTP::Response`](http://search.cpan.org/~gaas/HTTP-Message/lib/HTTP/Response.pm) class. Check the documentation. Saying `print $response->decoded_content` should be enough. – simbabque Jul 16 '12 at 07:14
  • @simbabque..I tried that but that results XML Response but in above code I am doing openconnection which results connectionid... Am I doing anything wrong in order to get that? – user1522786 Jul 16 '12 at 08:19
  • I don't understand. Please post the code you have used exactly as you have used it. Also, please [use code formatting](http://stackoverflow.com/editing-help#comment-formatting). – simbabque Jul 16 '12 at 08:36
  • @ simbabque...I am done with this the issue is to fetch the exact connection id..i did with regular expression but that is vain as I have to fecth with a module – user1522786 Jul 16 '12 at 11:12
  • Sorry for the delay I am able to fetch the id using Simple module.. – user1522786 Jul 18 '12 at 08:23