2013-04-09 620 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); 

享受:)