0

I am using below code for SOAP request.

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://example.com?WSDL",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS =>"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://Xyz.Abc\" xmlns:ns2=\"http://tempuri.org/\"><SOAP-ENV:Body><ns2:GetStatus><ns1:ReferenceNo>12345</ns1:ReferenceNo></ns2:GetStatus></SOAP-ENV:Body></SOAP-ENV:Envelope>",
      CURLOPT_HTTPHEADER => array(
        "Content-Type: text/xml"
      ),
    ));

$response = curl_exec($curl);
curl_close($curl);
echo $response;

Response: Getting below response when I set header('Content-type: application/xml'); in php script which is correct.

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <env:Header>...</env:Header>
    <env:Body>
        <GetStatusResponse xmlns:s1="http://Xyz.Abc" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns="http://tempuri.org/">
            <s1:StatusResponse>
                <s1:Test ResponseCode="INPROGRESS" ResponseMessage="Reference no. 12345"/>
            </s1:StatusResponse>
        </GetStatusResponse>
    </env:Body>
</env:Envelope>

How can I extract Body values from the response without just printing on browser?

Here is what I tried

Remove xml header and parse response string by simplexml_load_string method.

$xml = simplexml_load_string($response);
echo $xml;
$json = json_encode($response);
$arr = json_decode($json,true);
print_r($arr);

I also tried with SimpleXMLElement, but, it's printing empty response:

$test = new SimpleXMLElement($response);
echo $test;

But, it's printing empty result.

RNK
  • 5,582
  • 11
  • 65
  • 133

1 Answers1

1

SimpleXML is an object. It isn't the full XML string as you might think. Try this.

//Cast to string to force simpleXml to convert into a string
$xmlString = $xml->asXML();
echo $xmlString . "\n";

I'm pretty sure you can't do this because $response is XML. Trying to json_encode it doesn't make sense.

$json = json_encode($response);

I did this:

<?php
$x = '<?xml version="1.0" ?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>...</env:Header>
<env:Body>
<GetStatusResponse xmlns:s1="http://Xyz.Abc" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns="http://tempuri.org/">
    <s1:StatusResponse>
        <s1:Test ResponseCode="INPROGRESS" ResponseMessage="Reference no. 12345"/>
    </s1:StatusResponse>
</GetStatusResponse>
</env:Body>
</env:Envelope>';
$xml = simplexml_load_string($x);
echo $xml->asXml();
echo "\n";

And I get this output:

<?xml version="1.0"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>...</env:Header>
<env:Body>
<GetStatusResponse xmlns:s1="http://Xyz.Abc" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns="http://tempuri.org/">
    <s1:StatusResponse>
        <s1:Test ResponseCode="INPROGRESS" ResponseMessage="Reference no. 12345"/>
    </s1:StatusResponse>
</GetStatusResponse>
</env:Body>
</env:Envelope>

This explains how to specify namespaces. https://www.php.net/manual/en/simplexmlelement.attributes.php

$xml->registerXPathNamespace('e', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('s', 'http://Xyz.Abc');
$result = $xml->xpath('//s:Test');
$response = $result[0]->attributes();
echo "Response Code = " . $response['ResponseCode'] . "\n";
echo "Response Message = " . $response['ResponseMessage'] . "\n";
ryantxr
  • 4,119
  • 1
  • 11
  • 25
  • That's weird. It should be returning an instance of SimpleXMLElement. – ryantxr Mar 09 '20 at 20:46
  • Sorry. I called that method on other object. But, it's giving me string response from header part only. I am not getting any content from Body. – RNK Mar 09 '20 at 20:48
  • Actually, header and body are inside `env:Envelope` wrapper. – RNK Mar 09 '20 at 20:57
  • How can I get `ResponseCode` and `ResponseMessage` from the response? – RNK Mar 09 '20 at 21:00