2013-04-09 13 views
9

sto utilizzando cURL per inviare una richiesta a un servizio SOAP, io mando in POST corpo del XML che contiene i parametri, in risposta ricevo:conversione risposta XML SOAP a un oggetto o un array PHP

servizio Web: 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> 

Non ho abbastanza esperienza con i dati XML. Ho passato ore a cercare di convertire la risposta XML in un oggetto o array PHP, ma senza alcun successo.

Ho bisogno di leggere tutti i PropertyResults.

codice PHP:

$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); 

risposta

9

Il suggerimento di bksi non è sbagliato, tuttavia dal punto di vista tecnico in quanto XML è necessario accedere correttamente agli elementi dello spazio dei nomi. Questo funziona in modo più semplice utilizzando un'espressione XPath e la registrazione del namspace-uri per il proprio prefisso:

$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); 

uscita:

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" 

Se non si desidera utilizzare XPath, è necessario specificare lo spazio dei nomi mentre si attraversa, solo i bambini nello spazio dei nomi dell'elemento stesso sono disponibili direttamente se l'elemento stesso non è prefissato. Come l'elemento principale è preceduto è necessario prima di attraversare fino alla risposta:

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

allora si può fare uso della variabile $response come lo conoscete:

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

perché tale elemento non è prefissato . Poiché viene restituito un risultato più complesso, questo è probabilmente il migliore perché è possibile accedere facilmente a tutti i valori di risposta.

La tua domanda è simile a:

Forse il codice/descrizioni non sono utili, anche.

+0

Grazie per la risposta, l'impostazione dello spazio dei nomi xPath restituisce 500 errori, forse un errore di configurazione del server. La seconda soluzione funziona alla grande. – Hamza

2

Hm. È necessario utilizzare il client SOAP per farlo, non solo inviare richieste SOAP. PHP ha integrato le funzionalità SOAP http://php.net/manual/en/book.soap.php.

Esistono librerie di sapone personalizzate come NuSOAP http://sourceforge.net/projects/nusoap/.

La maggior parte dei framework php dispone anche di librerie SOAP.

+0

ho provato con nusoap, ma ottengo un errore che dice che SOAPAction manca anche se mando in PHP intestazione, e anche tramite il metodo di chiamata – Hamza

9

Si potrebbe considerare di passare la risposta SOAP attraverso un documento DOM e quindi convertirlo in un oggetto simplexml.

<?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; 
?> 

Tuttavia, questo può causare problemi con i caratteri speciali nella vostra risposta, come é e à. Altrimenti, funziona.

0

Un'altra soluzione, l'unica soluzione che ha funzionato per 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 :)