2013-04-09 638 views
9

我使用捲曲發送給SOAP服務的請求,在我POST體發送包含參數的XML中,響應予接收:SOAP的XML響應轉換爲PHP對象或數組

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> 

我沒有足夠的XML數據經驗。我花了數小時試圖將XML響應轉換爲PHP對象或數組,但沒有取得任何成功。

我需要讀取所有PropertyResults。

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

回答

9

bksi的提示沒有錯,但從技術上講,因爲這是XML,所以只需正確訪問命名空間元素即可。

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

輸出:

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" 

如果你不想使用XPath,您需要指定這通過使用XPath表達式和註冊namspace-URI到自己的前綴工作更輕鬆如果元素本身沒有前綴,則只有元素本身名稱空間中的子元素纔可以直接使用。作爲根元素的前綴,你首先需要穿越到響應:

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

然後你就可以使用$response可變的,你知道它:

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

,因爲該元素沒有前綴。由於返回更復雜的結果,這可能是最好的,因爲您可以輕鬆訪問所有響應值。

你的問題是相似的:

也許碼/描述有幫助的,太。

+0

感謝您的回答,設置xPath命名空間返回500錯誤,可能是服務器配置錯誤。第二個解決方案很好。 – Hamza 2013-04-09 22:57:32

2

嗯。你應該使用SOAP客戶端來做到這一點,而不僅僅是發送SOAP請求。 PHP集成了SOAP功能 http://php.net/manual/en/book.soap.php

有自定義肥皂庫,如NuSOAP http://sourceforge.net/projects/nusoap/

大多數PHP框架也有SOAP庫。

+0

我試着用的NuSOAP,但我得到一個錯誤,指出SOAPAction的缺失,即使我在PHP發送頭文件,也通過調用方法 – Hamza 2013-04-09 04:48:18

9

您可以考慮通過DOM Document傳遞SOAP響應,然後將其轉換爲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; 
?> 

但是,這可能會導致響應中的特殊字符出現問題,如é和à。否則,它的工作。

0

另一種解決方案,只爲我工作的解決方案:

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

享受:)