2

First time in my life trying to achieve implement wsdl service into web site. I am getting following response from service. I tried to parse response with following code but probably doing something wrong in somewhere. Could anyone help me to parse certain nodes from response?

Regards and Thanks

$xml = simplexml_load_string($result);


$hotels = $xml->children('http://schemas.xmlsoap.org/soap/envelope')->Body->children('http://axis.frontend.hydra.hotelbeds.com')->hoteldetailrs->hotel;

foreach ($hotels as $hotel) {
    echo ' 

        <hoteldetails>
            <h1>' .$hotel->name . '</h1>
            <h2>' .$hotel->code . '</h2>
        </hoteldetails>

     ';
}

Soap Response

  <!--?xml version="1.0" encoding="utf-8"?-->
<soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:body>
    <ns1:gethoteldetail xsi:type="xsd:string" xmlns:ns1="http://axis.frontend.hydra.hotelbeds.com">
      <hoteldetailrs xmlns="http://www.hotelbeds.com/schemas/2005/06/messages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://www.hotelbeds.com/schemas/2005/06/messages HotelDetailRS.xsd" echotoken="DummyEchoToken">
        <auditdata>
          <processtime>7</processtime>
          <timestamp>2014-09-01 13:39:27.027</timestamp>
          <requesthost>78.135.9.124</requesthost>
          <servername>FORM</servername>
          <serverid>FO</serverid>
          <schemarelease>2005/06</schemarelease>
          <hydracorerelease>2.0.201408281727</hydracorerelease>
          <hydraenumerationsrelease>1.0.201408281727</hydraenumerationsrelease>
          <merlinrelease>N/A</merlinrelease>
        </auditdata>
        <hotel xsi:type="ProductHotel">
          <code>50</code>
          <name>Aquahotel Aquamarina</name>
          <descriptionlist>
            <description type="HotelDescription" languagecode="ENG" languagename="Ingles">This attractive beach hotel is located on the sea front promenade of Santa Susanna, only 100 m from the beach. In the vicinity there are shops, bars, restaurants and night clubs. Girona Airport is 30 km away, Airport Barcelona-El Prat 60 km. The centre of Barcelona can be reached by train, calling at Plaça Catalunya. The hotel features 601 rooms, 24-hours reception, currency exchange, conference facilities, TV room, restaurant, 4 bars, outdoor pool, children's pool, playground, mini-club, cinema, supermarket and hairdresser. Facilities for disabled guests.</description>
          </descriptionlist>

          <contact>
            <address>
              <streettypeid>.</streettypeid>
              <streettypename> </streettypename>
              <streetname>AVENIDA DEL MAR</streetname>
              <number>16</number>
              <postalcode> 08398</postalcode>
              <city>SANTA SUSANA</city>
              <countrycode>ES</countrycode>
            </address>
            <emaillist>
              <email>aquahotel@aquahotel.com</email>
            </emaillist>
            <phonelist>
              <contactnumber type="phoneHotel">937678060</contactnumber>
              <contactnumber type="phoneBooking">902206306</contactnumber>
            </phonelist>
            <faxlist>
              <contactnumber>937678137</contactnumber>
            </faxlist>
            <weblist>
              <web>www.aquahotel.com</web>
            </weblist>
          </contact>
          <category type="SIMPLE" code="4EST" shortname="4*">4 STARS</category>
          <destination type="SIMPLE" code="LLM">
            <name>Costa Brava &amp; Costa Barcelona-Maresme</name>
            <zonelist>
              <zone type="SIMPLE" code="15">Santa Susana</zone>
            </zonelist>
          </destination>   
          <position latitude="41.63434" longitude="2.72169"></position>
        </hotel>
      </hoteldetailrs>
    </ns1:gethoteldetail>
  </soapenv:body>
</soapenv:envelope>
Hakan
  • 141
  • 3
  • 16
  • You can refer below link http://stackoverflow.com/questions/15892639/converting-soap-xml-response-to-a-php-object-or-array – v2solutions.com Sep 01 '14 at 13:29
  • Trying with following tells me node no longer exist. Any suggestion? echo "Hotel Name:" .$xml->children('soapenv', true)->children()->gethoteldetail->children()->hoteldetailrs->children()->hotel-children()->name . "\n"; – Hakan Sep 01 '14 at 16:52
  • you are actucally not speaking [SOAP](http://php.net/manual/de/book.soap.php) at all. – hek2mgl Sep 04 '14 at 10:47

3 Answers3

3

You're not targeting namespaces correctly. Use getNamespaces to see how to handle them if your struggle, and it becomes easy to target the wanted nodes :

$namespaces = $xml->getNamespaces(true);

$hotels = $xml->children($namespaces['soapenv'])
              ->body
              ->children($namespaces['ns1'])
              ->children()
              ->hoteldetailrs
              ->hotel;

foreach ($hotels as $hotel) {
    echo ' 
        <hoteldetails>
            <h1>' .$hotel->name . '</h1>
            <h2>' .$hotel->code . '</h2>
        </hoteldetails>
     ';
}

Output :

Aquahotel Aquamarina

50

Just let me know if you need more explanations on children() with namespaces given as parameters, but be sure to check the documentation of children() first

Clément Malet
  • 5,062
  • 3
  • 29
  • 48
  • SimpleXMLElement::children(): Node no longer exists '$namespaces = $xml->getNamespaces(true); var_dump($namespaces); $hotels = $xml->children($namespaces['soapenv']) ->body ->children($namespaces['ns1']) ->children() ->hoteldetailrs ->hotel;' – Hakan Sep 05 '14 at 10:49
  • @Hakan I executed this code again, and it's working as expected : http://codepad.org/i9Drp0pP – Clément Malet Sep 05 '14 at 11:08
  • Thank you very Much Clement Malet. My conversion from soap response to simple_xml seems that wrong. I am trying to solve problem. Thanks – Hakan Sep 05 '14 at 12:06
1
$client = new SoapClient("http://path.to/wsdl?WSDL");
$res = $client->SoapFunction(array('param1'=>'value','param2'=>'value'));
echo $res->gethoteldetail->city;
Rafik Bari
  • 4,867
  • 18
  • 73
  • 123
0

You can use following function to parse you xml data:

$str = '<!--?xml version="1.0" encoding="utf-8"?--> ..... ';
$ResponseData = xml2array($str, 0); 
$HotelData = $ResponseData['soapenv:envelope']['soapenv:body']['ns1:gethoteldetail']['hoteldetailrs'];
echo "<pre>"; print_r($HotelData); die;

Function:

function xml2array($contents, $get_attributes=1, $priority = 'tag') {

    if(!$contents) return array();

    if(!function_exists('xml_parser_create')) {
        return array();
    }

    $parser = xml_parser_create('');
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); 
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, trim($contents), $xml_values);
    xml_parser_free($parser);

    if(!$xml_values) return;

    $xml_array = array();
    $parents = array();
    $opened_tags = array();
    $arr = array();
    $current = &$xml_array;
    $repeated_tag_index = array();

    foreach($xml_values as $data) {

        unset($attributes,$value);
        extract($data);

        $result = array();
        $attributes_data = array();

        if(isset($value)) {         
            if($priority == 'tag')  $result = $value;  else  $result['value'] = $value;
        }   
        if(isset($attributes) and $get_attributes) {            
            foreach($attributes as $attr => $val) {             
                if($priority == 'tag') 
                    $attributes_data[$attr] = $val;
                else 
                    $result['attr'][$attr] = $val;
            }
        }       
        if($type == "open") {       
            $parent[$level-1] = &$current;          
            if(!is_array($current) or (!in_array($tag, array_keys($current)))) {            
                $current[$tag] = $result;               
                if($attributes_data) $current[$tag. '_attr'] = $attributes_data;                
                $repeated_tag_index[$tag.'_'.$level] = 1;
                $current = &$current[$tag];             
            } else {            
                if(isset($current[$tag][0])) {              
                    $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
                    $repeated_tag_index[$tag.'_'.$level]++;                 
                } else {                
                    $current[$tag] = array($current[$tag],$result);
                    $repeated_tag_index[$tag.'_'.$level] = 2;                   
                    if(isset($current[$tag.'_attr'])) {                 
                        $current[$tag]['0_attr'] = $current[$tag.'_attr'];
                        unset($current[$tag.'_attr']);
                    }
                }               
                $last_item_index = $repeated_tag_index[$tag.'_'.$level]-1;
                $current = &$current[$tag][$last_item_index];
            }

        } elseif($type == "complete") { 
            if(!isset($current[$tag])) {            
                $current[$tag] = $result;
                $repeated_tag_index[$tag.'_'.$level] = 1;
                if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;             
            } else {            
                if(isset($current[$tag][0]) and is_array($current[$tag])) {                 
                    $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
                    if($priority == 'tag' and $get_attributes and $attributes_data) {
                        $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
                    }
                    $repeated_tag_index[$tag.'_'.$level]++;                 
                } else {                
                    $current[$tag] = array($current[$tag],$result); 
                    $repeated_tag_index[$tag.'_'.$level] = 1;
                    if($priority == 'tag' and $get_attributes) {
                        if(isset($current[$tag.'_attr'])) { 
                            $current[$tag]['0_attr'] = $current[$tag.'_attr'];
                            unset($current[$tag.'_attr']);
                        }
                        if($attributes_data) {
                            $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
                        }
                    }
                    $repeated_tag_index[$tag.'_'.$level]++; 
                }
            }           
        } elseif($type == 'close') { 
            $current = &$parent[$level-1];
        }
    }

    return($xml_array);
}

I hope this will help you.

yogesh suhagiya
  • 498
  • 2
  • 6
  • 19