Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

HTTP Post of XML data

by hallikpapa (Scribe)
on Nov 14, 2007 at 02:33 UTC ( #650656=perlquestion: print w/replies, xml ) Need Help??
hallikpapa has asked for the wisdom of the Perl Monks concerning the following question:

I used XML::Writer to create XML data, and want to post was is created to a jboss application on port 8180. I found I couldn't use the OUTPUT => $output parameter correctly, like so:
use strict; use Spreadsheet::ParseExcel; use XML::Writer; use LWP::UserAgent; use Data::Dumper; my $browser = LWP::UserAgent->new; my $response = $browser->post('http://localhost:8180/request'); my $writer = XML::Writer->new( OUTPUT => $response, NEWLINES => 0, DATA_MODE => 1, DATA_INDENT => 2, );
Can't locate object method "print" via package "HTTP::Headers" at (eva +l 29) line 1.

Replies are listed 'Best First'.
Re: HTTP Post of XML data
by dorko (Parson) on Nov 14, 2007 at 03:37 UTC
    UPDATE: The original post was modified between the time I started writing and the time I posted this response. I'm sure my response looks odd now, so all bets are off on my response making any kind of sense.

    Warning: Although I've submitted XML via a POST, I've never used XML::Writer in combination with LWP::UserAgent like you're trying to do.

    From the docs for XML::Writer, the OUTPUT parameter of an XML::Writer object must be either an "object blessed into IO::Handle or one of its subclasses (such as IO::File), or a reference to a string." I'm pretty sure that $browser->post('http://localhost:8180/automanager/request') is neither of those.

    Plus, from the SYNOPSIS section of the XML::Writer docs, I'm pretty sure all you've done is created an object. It takes a bit more to actually create XML. This untested snippet is modified from the synopsis of the XML::Writer docs:

    my $output; my $writer = new XML::Writer(OUTPUT => \$output); $writer->startTag("greeting", "class" => "simple"); $writer->characters("Hello, world!"); $writer->endTag("greeting"); $writer->end(); print $output;
    If you then POST $output to your URL, I think that will do what you want. You'll need to specify $object as the Content of the POST (See the REQUEST METHODS section of the LWP::UserAgent docs. I remember having to use HTTP::Request::Common to build the request, but I don't remember why I needed to do that at the moment.)

    All this is from a quick read of the docs and from memory so it could all be way off base, but I think it at least points you in the right directions.



    -- Yeah, I'm a Delt.
      Sorry for editing the original post. I should have left the original and added some of my changed content. I will check out some of your suggestions. Any other suggestions on how you would post your XML data instead of using LWP::UserAgent? Update: So I created a little test script, and I saw the test XML post in the jboss log correctly:
      #!/usr/bin/perl use XML::Writer; use LWP::UserAgent; my $output; my $writer = new XML::Writer(OUTPUT => \$output); $writer->startTag("greeting", "class" => "simple"); $writer->characters("Hello, world!"); $writer->endTag("greeting"); $writer->end(); print $output; my $browser = LWP::UserAgent->new; my $url = 'http://localhost:8180/request'; my $response = $browser->post($url,Content => $output);
      And I added this at the end of my current script, and got this error:
      Not an ARRAY reference at /usr/share/perl5/HTTP/Request/ line + 83.
      my $browser = LWP::UserAgent->new; my $url = 'http://localhost:8180/request'; my $response = $browser->post($url,$writer);
      I tried with Content => \$writer, CONTENT => $writer, and just $writer. I'll keep fiddling with this unless someone else has suggestions on a better way to post this $writer to a specific port/url
        It looks like you are trying to post an XML::Writer object to a URL. Without looking at the API for either XML::Writer or LWP::UserAgent I can only guess, but I seriously, seriously doubt that procedure is possible. What you will want to post is not the writer object, but the output it produces.
Re: HTTP Post of XML data
by hallikpapa (Scribe) on Nov 14, 2007 at 17:27 UTC
    Well after looking around and talking to the java guy, I have found that the closing tag I am trying to send is incorrect. The XML::Writer wanted me to close the tag exactly the same way I opened it, so I put the whole
    $writer->endTag("manager xmlns:xsi= +stance");
    I need to just close it with:
    $writer->startTag("manager xmlns:xsi= +instance"); ..... .... .... $writer->endTag("manager"); $writer->end;
    But it is failing. In the documentation it states:
    NAMESPACES A true (1) or false (0, undef) value; if this parameter is present + and its value is true, then the module will accept two-member array +reference in the place of element and attribute names, as in the foll +owing example: my $rdfns = ""; my $writer = new XML::Writer(NAMESPACES => 1); $writer->startTag([$rdfns, "Description"]); The first member of the array is a namespace URI, and the second p +art is the local part of a qualified name. The module will automatica +lly generate appropriate namespace declarations and will replace the +URI part with a prefix.
    I was trying something like this:
    my $rdfns = ""; my $writer = new XML::Writer(OUTPUT => \$output, NAMESPACES => 1); $writer->startTag([$rdfns, "Description"]); $writer->startTag("greeting", "class" => "simple"); $writer->characters("Hello, world!"); $writer->endTag("greeting"); $writer->endTag("Description"); $writer->end(); print $output;
    But I get: Attempt to end element "ARRAY(0x814ec28)" with "Description" tag, when I don't have NAMESPACES => 1, and when I do add it, I get something similar: Attempt to end element "__NS1:Description" with "Description" tag Any leads Monks?
      After much fiddling, I am just down to how to do post an array @data, to the URL? It only posts the first line in the array. I have an array @data that holds a bunch of XML data. I am trying to send it all to port 8180 on the localhost to another application, but it is only sending the first line. What is the best way to send the entire array as is? A foreach loop would open a new connection each time instead of sending it all as one stream, correct? Cause when I do it like this, it only posts the opening tag.
      my $browser = LWP::UserAgent->new; ... ... ... open(FILE,"output.xml"); my @data = <FILE>; my $response = $browser->post( $url, Content => @data );

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://650656]
Approved by GrandFather
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (8)
As of 2018-06-25 20:35 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (128 votes). Check out past polls.