Link to home
Start Free TrialLog in
Avatar of prevostpilot
prevostpilotFlag for United States of America

asked on

using curl to send xml

i'm having a problem submitting an xml file to a vendor website.

the xml is specified by the vendor as something like this:
<outter>
  <inner1>some text</inner1>
  <inner2>more text</inner2>
</outter>

the vendor supplied me with a test xml file/string that looks something like
  <outter><inner1>hello</inner1><inner2>world</inner2></outter>

using their test text box, this text works just fine.

i'm trying to test using curl but keep getting
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">Server was unable to process request. ---&gt; Data at the root level is invalid. Line 1, position 1.</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>

as a response, saying "data at the root level is invalid".

their message service page gives details for various interfaces, soap, http get, and http post - the http post spec looks like this:

  POST /Service1.asmx/ProcessXML HTTP/1.1
  Host: service1.vendordomain.com
  Content-Type: application/x-www-form-urlencoded
  Content-Length: length

  inpXML=string

i've used
  curl -F "inpXML=<outter><inner1>hello</inner1><inner2>world</inner2></outter>" http://service1.vendordomain.com/script.asmx

  curl -d "inpXML= the url encoded version of the same string" url

plus both these using <?xml version=\"1.0\" encoding=\"application/x-www-form-urlencoded\"?>, eg.,

  curl -d "inpXML=<?xml version=\"1.0\" encoding=\"application/x-www-form-urlencoded\"?> the url encoded version of the same string" url

still i get the "data at the root level is invalid" response - whats the proper curl switches etc to get this to work?

tnx
Avatar of Meir Rivkin
Meir Rivkin
Flag of Israel image

try using this function to send xml over POST (from http://stackoverflow.com/questions/238784/php4-send-xml-over-https-post-via-curl)
function sendXmlOverPost($url, $xml) {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);

  // For xml, change the content-type.
  curl_setopt ($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));

  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // ask for results to be returned
  if(CurlHelper::checkHttpsURL($url)) { 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  }

  // Send to remote and return data to caller.
  $result = curl_exec($ch);
  curl_close($ch);
  return $result;
}

Open in new window

Avatar of prevostpilot

ASKER

i've tried something very much like this already (actually, this is why i was trying to use curl to debug).

PARTIAL ANSWER:
i used ideas from the google checkout/shopping cart class.

using your fcn and the value of $inpXML set to
  <?xml version=\"1.0\" encoding=\"utf-8\"?><outer><inner1>hello</inner1><inner2>world</inner2></outer>

i get this response:

  soap:VersionMismatchPossible SOAP version mismatch: Envelope namespace was
  unexpected. Expecting http://schemas.xmlsoap.org/soap/envelope/.

instead of the response indicated in my orig post.  i massaged my code
around until i got the same response.  the diff is, i was using this
  $postData = array('inpXML' => $inpXML);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

instead of your version, this:
  curl_setopt($ch, CURLOPT_POSTFIELDS, $inpXML);

the php documentation sez,
CURLOPT_POSTFIELDS         ... or as an array with the field name
                         as key and field data as value.         

and the example code in the php doc illustrates this:
  $data = array('name' => 'Foo', 'file' => '@/home/user/test.png');
  curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

not sure whats up with that....

furthermore, the vendor page says the http post format should be:

  POST /service1.asmx/ProcessXML HTTP/1.1
  Host: srvtest.myVendorDomain.com
  Content-Type: application/x-www-form-urlencoded
  Content-Length: length
 
  inpXML=string

this seems to indicate they're looking for something that looks like
a submitted form with the form field id set to "inpXML", and the field value of
urlencode($xmlString)

when i curl the exact same string using
  curl -d "inpXML='string'" url/script.asmx
    or
  curl -d "inpXML=urlencode('string')" url/script.asmx
    or
  curl -d "inpXML=urlencode('string')" -H "Content-Type: application/x-www-form-urlencoded" url/script.asmx
    or
  curl -d "inpXML='string'" -H "Content-Type: text/xml" url/script.asmx

(where urlencoded('string') means the encoded version of the string)

i still get a soap response of
  Data at the root level is invalid. Line 1, position 1.


=======================
all of these,
  curl_setopt ($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
  or
  curl_setopt ($ch, CURLOPT_HTTPHEADER, Array("Content-Type: application/x-www-form-urlencoded"));

used with
  curl_setopt($ch, CURLOPT_POSTFIELDS, $inpXML);

produce

  soap:VersionMismatchPossible SOAP version mismatch: Envelope namespace was unexpected. Expecting http://schemas.xmlsoap.org/soap/envelope/.

=======================
changing to either
  curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode('inpXML=' . $inpXML));
  or
  curl_setopt($ch, CURLOPT_POSTFIELDS, array('inpXML' => $inpXML));
 
produces
  soap:ReceiverServer was unable to process request. ---> Data at the root level is invalid. Line 1, position 1.
=======================



a couple questions:
is this the CurlHelper class from the google facebook code?
why is the response a soap msg?
why is soap involved?  do i need a soap namespace?  (maybe i'll try that next)

and finally, what is the curl syntax to get the same behavior as your fcn?

thanks

ASKER CERTIFIED SOLUTION
Avatar of prevostpilot
prevostpilot
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial