ashishg0310 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,.

Perl file

#!/usr/bin/perl use strict; use XML::Simple; use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $server_endpoint = "http://localhost/cgi-bin/stackoverflow_ +in.cgi"; # set custom HTTP request header fields my $req = HTTP::Request->new(POST => $server_endpoint); $req->header('content-type' => 'application/json'); my $xml = XMLin('parsetest.xml',forcearray => 1); my $customer; foreach my $customer(@{$xml->{customer}}){ print "$customer->{first_name}->[0]\n"; print "$customer->{last_name}->[0]\n"; print "$customer->{dob}->[0]\n"; print "$customer->{email}->[0]\n"; } # add POST data to HTTP request body my $post_data1 = $customer->{first_name}->[0]; my $post_data2 = $customer->{last_name}->[0]; my $post_data3 = $customer->{dob}->[0]; my $post_data4 = $customer->{email}->[0]; $req->content($post_data1,$post_data2,$post_data3,$post_data4); my $resp = $ua->request($req); if ($resp->is_success) { my $message = $resp->decoded_content; print "Received reply: $message\n"; } else { print "HTTP POST error code: ", $resp->code, "\n"; print "HTTP POST error message: ", $resp->message, "\n"; }

CGI file

#!/usr/bin/perl # Title Processor.pl use CGI; use DBI; my $cgi = CGI->new; my $local = $cgi->param("POSTDATA"); print $cgi->header(-type => "application/json", -charset => "utf-8"); print "$local was received"; my $username = "test"; my $password = "test"; my $dsn = "dbi:mysql:detailsof:127.0.0.1"; my $dbh = DBI->connect($dsn,$username,$password,{RaiseError => 1,Print +Error => 0}) or die "cannot connect to database : $DBI::errstr"; my $sth = $dbh->prepare(qq{INSERT INTO cust_details.c_details(f_name,l +_name,dob_email) VALUES ('$customer->{first_name}->[0]','$customer->{ +last_name}->[0]','$customer->{dob}->[0]','$customer->{email}->[0]')}) +; $sth->execute() || die $DBI::errstr; $sth->finish(); $dbh->disconnect;

o/p: Received reply : was received.

i am not getting my parsed data which should be between reply and was.

Replies are listed 'Best First'.
Re: unable to pass data
by NetWallah (Canon) on May 21, 2014 at 23:34 UTC
    I tried out your code after eliminating the XML and mysql-dbi - it seemd to work.

    changed the lwp code to hard-code:

    my $post_data1 = "first_name"; my $post_data2 = "Last name"; my $post_data3 = "10/10/1999"; my $post_data4 = "someone\@somwehere.com";
    When the LWP is run, I get:
    Received reply: first_name was received
    Perhaps the content retrieved from XML does not match your code's expectations.

            What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
                  -Larry Wall, 1992

Re: unable to pass data
by cord-bin (Friar) on May 22, 2014 at 14:45 UTC
    There are few mistakes that should be corrected in your scripts. Your CGI script should receive through the param() function the information sent from your first script that is parsing the xml file. Your xml parse is ok, I tested:
    Platon$ ./t-pass-data.pl Frank Sanbeans 3/10 frank@example.com Sandy Sanbeans 4/15 sandy@example.com
    Your CGI script should be the one you call from this:
    my $server_endpoint = "http://localhost/cgi-bin/stackoverflow_in.cgi";
    stackoverflow_in.cgi should be the name of your second perl file. This code is wrong:
    my $sth = $dbh->prepare(qq{INSERT INTO cust_details.c_details(f_name,l +_name,dob_email) VALUES ('$customer->{first_name}->[0]','$customer->{ +last_name}->[0]','$customer->{dob}->[0]','$customer->{email}->[0]')}) +;
    You should use the param() function go get the passed data from the first program. You don't have access to $customer->{last_name}... here! You could pass data in the first script with names like
    my $firstname = param('firstname'); my $lastname = param('lastname');
    And then get it to the second CGI script for the insert in sql.
Re: unable to pass data
by Anonymous Monk on May 22, 2014 at 06:08 UTC
    XML CODE which i am trying to send
    <?xml version="1.0"?> <customer-data> <customer> <first_name>Frank</first_name> <last_name>Sanbeans</last_name> <dob>3/10</dob> <email>frank@example.com</email> </customer> <customer> <first_name>Sandy</first_name> <last_name>Sanbeans</last_name> <dob>4/15</dob> <email>sandy@example.com</email> </customer> </customer-data>
Re: unable to pass data
by ashishg0310 (Novice) on May 22, 2014 at 03:47 UTC
    To:NetWallah I started learning perl few months back only..so i am not much familiar about the data match and oll. Hope you will help me out. I dont want to pass hard coded values.. I want to send that parsed data..how could i do that..?
      Show us a sample of the original XML (Sufficient to allow extraction of one complete set of related data). That will help verify your code.

      Alternatively, you could use the Data::Dump module to examine the contents you extracted from the XML, and verify your indexing corresponds to the data extracted.

              What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
                    -Larry Wall, 1992

Re: unable to pass data
by ashishg0310 (Novice) on May 22, 2014 at 18:26 UTC
    Hi cord-bin : sure i will try this.. But in this scenario i am parsing only one XML by giving file name and node name.. Suppose i want to do the same thing as above with multiple different XML files..and want to insert to data of XML file into their respective database.. And i don't want to do it by hard coding as above i did.. Is there any way to automate this..?

      You could post the xml to the server and then process with XML::Twig and assign different code block to the different elements. Something like this;

      Client code

      #!/usr/bin/perl use strict; use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $server_endpoint = "http://localhost/test/process2.cgi"; # set custom HTTP request header fields my $req = HTTP::Request->new(POST => $server_endpoint); $req->header('content-type' => 'application/json'); my $xml = do { local $/; <DATA> }; $req->content($xml); my $resp = $ua->request($req); if ($resp->is_success) { my $message = $resp->decoded_content; print "Received reply:\n$message\n"; } else { print "HTTP POST error code: ", $resp->code, "\n"; print "HTTP POST error message: ", $resp->message, "\n"; } __DATA__ <?xml version="1.0"?> <data> <customer-data> <customer> <first_name>Frank</first_name> <last_name>Sanbeans</last_name> <dob>3/10</dob> <email>frank@example.com</email> </customer> <customer> <first_name>Sandy</first_name> <last_name>Sanbeans</last_name> <dob>4/15</dob> <email>sandy@example.com</email> </customer> </customer-data> <supplier-data> <supplier> <name>Supplier 1</name> <address>Address 1</address> <tel-no>012345</tel-no> </supplier> </supplier-data> </data>
      Server code
      #!perl use strict; use CGI; use DBI; #use CGI::Carp 'fatalsToBrowser'; use XML::Twig; my $dbh = dbh(); # connect # customer database my $sql1 = 'INSERT INTO c_details (f_name,l_name,dob,email) VALUES (?,?,?,?)'; my $sth1 = $dbh->prepare($sql1); # supplier database my $sql2 = 'INSERT INTO s_details (name,address,tel_no) VALUES (?,?,?)'; my $sth2 = $dbh->prepare($sql2); my $cgi = CGI->new; print $cgi->header(-type => "application/json", -charset => "utf-8"); my $xml = $cgi->param("POSTDATA"); # process file my $t = XML::Twig->new( twig_handlers => { 'customer' => \&customer, 'supplier' => \&supplier, } ); $t->parse($xml); sub customer { my ($t,$elt) = @_; my @f=(); $f[0] = $elt->field('first_name'); $f[1] = $elt->field('last_name'); $f[2] = $elt->field('dob'); $f[3] = $elt->field('email'); $sth1->execute(@f) or die $DBI::errstr; print join "\t",$sql1,@f,"\n"; } sub supplier { my ($t,$elt) = @_; my @f=(); $f[0] = $elt->field('name'); $f[1] = $elt->field('address'); $f[2] = $elt->field('tel-no'); $sth2->execute(@f) or die $DBI::errstr; print join "\t",$sql2,@f,"\n"; }
      poj
Re: unable to pass data
by Anonymous Monk on Jun 04, 2014 at 07:38 UTC

    The script worked..after removing NBA.XML as it was invalid XML. OK i will try to follow script given by you and will get back to you for some further suggestion. Hope its OK..Thanks a lot for the help.

Re: unable to pass data
by Anonymous Monk on Jun 03, 2014 at 08:36 UTC
    To: Poj Trying to parse data from client to server and the inserting into database. case 1) The same worked when i tried to parse and insert directly by giving file name i.e nba.xml instead of variable $xml case 2)The same code worked when i only tried to parse by giving variable $xml in parse file..and not insert.. i.e parsing was successful But it gives me below error when i tried to insert the same after parsing Error message: HTTP POST error code: 500 HTTP POST error message: Internal Server Error
    customer.xml <?xml version="1.0"?> <customer> <first_name>Frank</first_name> <last_name>Sanbeans</last_name> <dob>3/10</dob> <email>frank@example.com</email> </customer>
    nba.xml <?xml version="1.0"?> <stats><player><name>Houston, Allan</name><g>69</g><ppg>20.1</ppg><rpg +>3.4</rpg><apg>2.8</apg><blk>14</blk></player> <player><name>Sprewell, Latrell</name><g>69</g><ppg>19.2</ppg><rpg>4.5 +</rpg><apg>4.0</apg><blk>15</blk></player> <player><name>Ewing, Patrick</name><g>49</g><ppg>14.6</ppg><rpg>10.0</ +rpg><apg>1.0</apg><blk>68</blk></player> </stats>
    supplier.xml <?xml version="1.0"?> <supplier-data> <supplier> <name>Supplier 1</name> <address>Address 1</address> <tel-no>012345</tel-no> </supplier> </supplier-data>
    twig_client_parse #!/usr/bin/perl
    use strict; use warnings; use XML::Simple; use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $server_endpoint = "http://localhost/cgi-bin/RnD/twig/twig_rcvr_ser +ver.cgi"; # set custom HTTP Request header fields my $xml; my $req = HTTP::Request->new(POST => $server_endpoint); $req->header('content-type' => 'text/xml'); # for descending order use # my @files = reverse(glob("*.xml")); my @files = (glob("*.xml")); print "@files\n"; my $test; foreach $test(@files){ #print "this element: $test \n "; open FILE, $test or die $!; while(<FILE>){ $xml .= $_; #print $xml; } } $req->content($xml); my $resp = $ua->request($req); if ($resp->is_success){ my $message = $resp->decoded_content; print "Received reply:\n $message\n"; } else { print "HTTP POST error code: ", $resp->code, "\n"; print "HTTP POST error message: ", $resp->message, "\n"; }
    twig_rcvr_server
    #!/usr/bin/perl use strict; use warnings; use CGI; use DBI; use XML::Twig; use CGI::Carp 'fatalsToBrowser'; my $cgi = CGI->new; print $cgi->header(-type => "text/xml", -charset => "utf-8"); my $xml = $cgi->param("POSTDATA"); print "the data $xml is received"; my $username = "abcxyz"; my $password = "xyzabc"; my $dsn = "dbi:mysql:twig:127.0.0.1"; my $dbh = DBI->connect($dsn,$username,$password) or die "Cannot connec +t to database: $DBI::errstr"; my $sql1 = 'INSERT INTO twig_test(name,ppg,rpg,apg,g,blk) VALUES(?,?,?,?,?,?)'; my $sth1 = $dbh->prepare($sql1); my $sql2 = 'INSERT INTO customer(first_name,last_name,dob,email) VALUES(?,?,?,?)'; my $sth2 = $dbh->prepare($sql2); my $sql3 = 'INSERT INTO supplier(name,address,tel_no) VALUES(?,?,?)'; my $sth3 = $dbh->prepare($sql3); #test if($dbh){ print "print successfully connected to the database"; } my $twig = new XML::Twig( twig_handlers => {player => \&player, customer => \&customer, supplier => \&supplier} ); $twig->parsefile($xml); #$twig->print; sub player {my ($twig,$player) = @_; my @f=(); $f[0] = $player->field('name'); $f[1] = $player->field('ppg'); $f[2] = $player->field('rpg'); $f[3] = $player->field('apg'); $f[4] = $player->field('g'); $f[5] = $player->field('blk'); print $f[0], "\n"; print $f[1], "\n"; print $f[2], "\n"; print $f[3], "\n"; print $f[4], "\n"; print $f[5], "\n"; #print "\n"; $sth1->execute(@f) or die $DBI::errstr; } sub customer {my ($twig,$customer) = @_; my @f=(); $f[0] = $player->field('first_name'); $f[1] = $player->field('last_name'); $f[2] = $player->field('dob'); $f[3] = $player->field('email'); print $f[0], "\n"; print $f[1], "\n"; print $f[2], "\n"; print $f[3], "\n"; #print "\n"; $sth2->execute(@f) or die $DBI::errstr; } sub supplier {my ($twig,$supplier) = @_; my @f=(); $f[0] = $player->field('name'); $f[1] = $player->field('address'); $f[2] = $player->field('tel-no'); print $f[0], "\n"; print $f[1], "\n"; print $f[2], "\n"; #print "\n"; $sth3->execute(@f) or die $DBI::errstr; }

      There are some obvious errors ; customer and supplier subroutines both have
      $player->field

      Regarding the client, joining the 3 xml files into one will not produce a valid xml file.
      As a first step try this revised server code with xml from DATA . Just open URL in browser.

      poj
Re: unable to pass data
by Anonymous Monk on Jun 03, 2014 at 19:28 UTC
    hi poj :

    please do not get frustated with my question as i do not have much experience with perl just started learning. The code worked which you gave.Thanx for dat.. But i cannot use DATA as i want to send the xml files from my client code,as it will be sending multiple xml files in some few fixed interval by reading from a particular directory. But why you saying "joining the 3 xml files into one will not produce a valid xml file". Then why it works in parsing..?and why not in insertion..?

      You have many components so it's important to get each one working separately before trying them all togther

      Try the script with
      my $xml = do { local $/; <DATA> };
      as I have provided and only if that works change it to
      my $xml = $cgi->param("POSTDATA");

      If it fails at the point it means that the XML being sent is not valid and we can move on to sorting out the client code

      If the script I provided does not work then you have a bigger problem !

      poj