converting SOAP XML response to a PHP object or array

43,606

Solution 1

The hint of bksi is not that wrong, however technically as this is XML you only need to access the namespaced elements properly. This works more easy by using an XPath expression and registering the namspace-uri to your own prefix:

$soap = simplexml_load_string($soapXMLResult);
$soap->registerXPathNamespace('ns1', 'http://ivectorbookingxml/');
$test = (string) $soap->xpath('//ns1:SearchResponse/ns1:SearchResult/ns1:SearchURL[1]')[0];
var_dump($test);

Output:

string(100) "http://www.lowcostholidays.fr/dl.aspx?p=0,8,5,0&date=10/05/2013&duration=15&room1=2,1,0_5&regionid=9"

If you don't want to use XPath, you need to specify the namespace while you traverse, only the children in the namespace of the element itself are available directly if the element itself is not prefixed. As the root element is prefixed you first need to traverse up to the response:

$soap     = simplexml_load_string($soapXMLResult);
$response = $soap->children('http://schemas.xmlsoap.org/soap/envelope/')
                     ->Body->children()
                         ->SearchResponse
;

Then you can make use of the $response variable as you know it:

$test = (string) $response->SearchResult->SearchURL;

because that element is not prefixed. As a more complex result is returned this is probably the best because you can easily access all the response values.

Your question is similar to:

Maybe the code/descriptions there are helpful, too.

Solution 2

Another solution, the only solution that worked for me :

$xml = $soap_xml_result;
$xml = preg_replace("/(<\/?)(\w+):([^>]*>)/", '$1$2$3', $xml);
$xml = simplexml_load_string($xml);
$json = json_encode($xml);
$responseArray = json_decode($json, true); // true to have an array, false for an object
print_r($responseArray);

Enjoy :)

Solution 3

You could consider passing the SOAP response through a DOM Document, and then converting it into a simplexml object.

<?php
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($soap_response);
libxml_clear_errors();
$xml = $doc->saveXML($doc->documentElement);
$xml = simplexml_load_string($xml);
$response = $xml->body->envelope->body->searchresponse;
//print_r($response); exit;
echo $response->searchresult->returnstatus->success;
echo '<br>';
echo $response->searchresult->searchurl;
?>

However, this may cause problems with special characters in your response, like é and à. Else, it works.

Solution 4

Hm. You should use SOAP client to do that, not just send SOAP requests. PHP has integrated SOAP functionalities http://php.net/manual/en/book.soap.php.

There are custom soap libraries like NuSOAP http://sourceforge.net/projects/nusoap/.

Most of php frameworks has SOAP libraries too.

Share:
43,606
Hamza
Author by

Hamza

Updated on January 05, 2020

Comments

  • Hamza
    Hamza over 4 years

    I'm using cURL to send an request to a SOAP service, I send in POST Body the XML containing parameters, in response I receive:

    Web service: http://lcbtestxmlv2.ivector.co.uk/soap/book.asmx?WSDL

    <?xml version="1.0" encoding="UTF-8"?>
        <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
           <soap:Body>
              <SearchResponse xmlns="http://ivectorbookingxml/">
                 <SearchResult>
                    <ReturnStatus>
                       <Success>true</Success>
                       <Exception />
                    </ReturnStatus>
                    <SearchURL>http://www.lowcostholidays.fr/dl.aspx?p=0,8,5,0&amp;date=10/05/2013&amp;duration=15&amp;room1=2,1,0_5&amp;regionid=9</SearchURL>
                    <PropertyResults>
                       <PropertyResult>
                          <TotalProperties>215</TotalProperties>
                          <PropertyID>1795</PropertyID>
                          <PropertyName>Hotel Gaddis</PropertyName>
                          <Rating>3.0</Rating>
                          <Country>Egypte</Country>
                          <Resort>Louxor</Resort>
                          <Strapline>Cet établissement confortable propose un très bon service à un bon rapport qualité-prix. Cet hôtel de 6 étages compte 55 chambres et comprend une terrasse, une réception avec coffre-fort et ascenseur,</Strapline>
                          <Description>Cet établissement confortable propose un très bon service à un bon rapport qualité-prix. Cet hôtel de 6 étages compte 55 chambres et comprend une terrasse, une réception avec coffre-fort et ascenseur,...</Description>
                          <CMSBaseURL>http://lcbtestxml1.ivector.co.uk/content/DataObjects/Property/Image/</CMSBaseURL>
                          <MainImage>image_1795_v1.jpg</MainImage>
                          <MainImageThumbnail>imagethumb_1795_v1.jpg</MainImageThumbnail>
                          <SearchURL>http://www.lowcostholidays.fr/dl.aspx?p=0,8,5,0&amp;date=10/05/2013&amp;duration=15&amp;room1=2,1,0_5&amp;regionid=9&amp;propertyid=1795</SearchURL>
                          <RoomTypes>
                             <RoomType>
                                <Seq>1</Seq>
                                <PropertyRoomTypeID>690039000</PropertyRoomTypeID>
                                <MealBasisID>3</MealBasisID>
                                <RoomType>Twin/double Room</RoomType>
                                <RoomView />
                                <MealBasis>Petit Déjeuner</MealBasis>
                                <NonRefundableRates>false</NonRefundableRates>
                                <SubTotal>150.58</SubTotal>
                                <Discount>0</Discount>
                                <Total>150.58</Total>
                                <Adults>2</Adults>
                                <Children>1</Children>
                                <Infants>0</Infants>
                                <Errata />
                             </RoomType>
                             <RoomType>
                                <Seq>1</Seq>
                                <PropertyRoomTypeID>690039001</PropertyRoomTypeID>
                                <MealBasisID>7</MealBasisID>
                                <RoomType>Twin/double Room</RoomType>
                                <RoomView />
                                <MealBasis>Demi-Pension</MealBasis>
                                <NonRefundableRates>false</NonRefundableRates>
                                <SubTotal>291.64</SubTotal>
                                <Discount>0</Discount>
                                <Total>291.64</Total>
                                <Adults>2</Adults>
                                <Children>1</Children>
                                <Infants>0</Infants>
                                <Errata />
                             </RoomType>
                             <RoomType>
                                <Seq>1</Seq>
                                <PropertyRoomTypeID>690039002</PropertyRoomTypeID>
                                <MealBasisID>5</MealBasisID>
                                <RoomType>Double/twin Room</RoomType>
                                <RoomView />
                                <MealBasis>Pension Complète</MealBasis>
                                <NonRefundableRates>false</NonRefundableRates>
                                <SubTotal>529.22</SubTotal>
                                <Discount>0</Discount>
                                <Total>529.22</Total>
                                <Adults>2</Adults>
                                <Children>1</Children>
                                <Infants>0</Infants>
                                <Errata />
                             </RoomType>
                          </RoomTypes>
                       </PropertyResult>
                    </PropertyResults>
                 </SearchResult>
              </SearchResponse>
           </soap:Body>
        </soap:Envelope>
    

    I don't have enough experience with XML data. I spent hours trying to convert the XML response to a PHP object or array, but without any success.

    I need to read all PropertyResults.

    PHP Code:

    $xml = simplexml_load_string($soap_xml_result);
    
    $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
    $xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
    $xml->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
    
    $test = (string) $xml->Body->SearchResponse->SearchResult->SearchURL;
    var_export($test);
    
  • Hamza
    Hamza about 11 years
    I tried with nuSOAP, but I get an error saying that SOAPAction is missing even if I send it in PHP header, and also via call method
  • Hamza
    Hamza about 11 years
    Thanks for your answer, setting the xPath namespace returns 500 error, maybe a server misconfiguration. Second solution works great.