2013-07-02 5 views
4

Пожалуйста, прочитайте выделенную строку ниже, прежде чем комментировать, что это может быть дубликат. Это не имеет ничего общего с SimpleXML.Преобразование многомерного массива в XML

Позвольте мне начать с того, чтобы показать, как должен быть выложен XML. Пожалуйста, игнорируйте пространства имен:

<hot:SearchHotels> 
    <hot:request> 
     <hot1:Destination>?</hot1:Destination> 
     <hot1:HotelCityName>?</hot1:HotelCityName> 
     <hot1:HotelLocationName>?</hot1:HotelLocationName> 
     <hot1:HotelName>?</hot1:HotelName> 
     <hot1:CheckIn>?</hot1:CheckIn> 
     <hot1:CheckOut>?</hot1:CheckOut> 
     <hot1:RoomsInformation> 
      <!--Zero or more repetitions:--> 
      <hot1:RoomInfo> 
       <hot1:AdultNum>?</hot1:AdultNum> 
       <hot1:ChildNum>?</hot1:ChildNum> 
       <!--Optional:--> 
       <hot1:ChildAges> 
       <!--Zero or more repetitions:--> 
       <hot1:ChildAge age="?"/> 
       </hot1:ChildAges> 
      </hot1:RoomInfo> 
     </hot1:RoomsInformation> 
     <hot1:MaxPrice>?</hot1:MaxPrice> 
     <hot1:StarLevel>?</hot1:StarLevel> 
     <hot1:AvailableOnly>?</hot1:AvailableOnly> 
     <hot1:PropertyType>?</hot1:PropertyType> 
     <hot1:ExactDestination>?</hot1:ExactDestination> 
    </hot:request> 
    </hot:SearchHotels> 

Уведомление под hot1: RoomsInformation is RoomInfo. Я должен иметь возможность отправлять несколько узлов RoomInfo. Но я использую класс PHP для преобразования массива в этот объект, который должен быть отправлен через SOAP.

Вот мой массив, прежде чем он преобразуется в объект:

$param = array(
      "Destination" => $destcode, 
      "HotelCityName" => $city, 
      "HotelLocationName" => "", 
      "HotelName" => "", 
      "CheckIn" => date("Y-m-d", strtotime($checkin)), 
      "CheckOut" => date("Y-m-d", strtotime($checkout)), 
      "RoomsInformation" => array (
       "RoomInfo" => array(
         "AdultNum" => 2, 
         "ChildNum" => 1, 
         "ChildAges" => array(
          "ChildAge" => array(
           "age"=>11 
          ) 
         ) 
        ), 
       "RoomInfo" => array(
         "AdultNum" => 1, 
         "ChildNum" => 0, 
         "ChildAges" => array(
          "ChildAge" => array(
           "age"=>0 
          ) 
         ) 
        ) 
      ), 
      "MaxPrice" => 0, 
      "StarLevel" => 0, 
      "AvailableOnly" => "false", 
      "PropertyType" => "NotSet", 
      "ExactDestination" => "false" 
     ); 

$param = arrayToObject($param) ; 
$obj = new stdClass(); 
$obj->request=$param; 
$result = $test->SearchHotels($obj) ; 

Проблема заключается в том, что после преобразования в объект, есть только один RoomInfo и его последним. Моя мысль состоит в том, что массив RoomsInformation имеет 2 идентичных имени KEY. Так как я могу сделать эту работу?

Для информации, вот это класс SOAP я использую и функция arrayToObject:

http://pastebin.com/SBUN0FAF

+3

Возможный дубликат [Как преобразовать массив в SimpleXML] (http://stackoverflow.com/q/1397036/1503018) – sectus

+1

Если вы используете SOAP, то встроенный SoapClient может обрабатывать массив – Fracsi

+2

Вы можете ' t, а не с этим массивом. Независимо от того, сколько у вас записей «RoomsInformation», если у них есть один и тот же ключ, они на самом деле только один. –

ответ

7

Проблема заключается в том, ваш массив является недействительным, как вы подозревали из ключей дубликатов. Один из способов решить эту проблему, чтобы обернуть каждый «RoomInfo» в своем собственном массиве так:

$param = array(
    "Destination" => $destcode, 
    "HotelCityName" => $city, 
    "HotelLocationName" => "", 
    "HotelName" => "", 
    "CheckIn" => date("Y-m-d", strtotime($checkin)), 
    "CheckOut" => date("Y-m-d", strtotime($checkout)), 
    "RoomsInformation" => array (
     array(
      "RoomInfo" => array(
       "AdultNum" => 2, 
       "ChildNum" => 1, 
       "ChildAges" => array(
        "ChildAge" => array(
         "age"=>11 
        ) 
       ) 
      ), 
     ), 
     array(
      "RoomInfo" => array(
       "AdultNum" => 1, 
       "ChildNum" => 0, 
       "ChildAges" => array(
        "ChildAge" => array(
         "age"=>0 
        ) 
       ) 
      ) 
     ) 
    ), 
    "MaxPrice" => 0, 
    "StarLevel" => 0, 
    "AvailableOnly" => "false", 
    "PropertyType" => "NotSet", 
    "ExactDestination" => "false" 
); 

И вы можете сгенерировать XML так:

// create simpleXML object 
$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><SearchHotels></SearchHotels>"); 
$node = $xml->addChild('request'); 

// function call to convert array to xml 
array_to_xml($param, $node); 

// display XML to screen 
echo $xml->asXML(); 
die(); 

// function to convert an array to XML using SimpleXML 
function array_to_xml($array, &$xml) { 
    foreach($array as $key => $value) { 
     if(is_array($value)) { 
      if(!is_numeric($key)){ 
       $subnode = $xml->addChild("$key"); 
       array_to_xml($value, $subnode); 
      } else { 
       array_to_xml($value, $xml); 
      } 
     } else { 
      $xml->addChild("$key","$value"); 
     } 
    } 
} 

Я объясняю функцию array_to_xml к замечательный автор здесь: https://stackoverflow.com/a/5965940/2200766

+1

Не пытайтесь использовать SimpleXML. Мне нужно конвертировать в объект для отправки через SOAP-клиент. Внесение изменений, которые вы предложили, приводит к тому, что оба PropertyInfo полностью исчезают. – swg1cor14

+0

См. Редактирование, которое я добавил до конца вопроса – swg1cor14

0

Похоже, что у вас должен быть такой массив;

$param = array(
     "Destination" => $destcode, 
     "HotelCityName" => $city, 
     "HotelLocationName" => "", 
     "HotelName" => "", 
     "CheckIn" => date("Y-m-d", strtotime($checkin)), 
     "CheckOut" => date("Y-m-d", strtotime($checkout)), 
     "RoomsInformation" => array (
      "RoomInfo" => array(
        array(
        "AdultNum" => 2, 
        "ChildNum" => 1, 
        "ChildAges" => array(
         "ChildAge" => array(
          "age"=>11 
         ) 
        ) 
       ), 
        array(
        "AdultNum" => 1, 
        "ChildNum" => 0, 
        "ChildAges" => array(
         "ChildAge" => array(
          "age"=>0 
         ) 
        ) 
       ) 
      ) 
     ), 
     "MaxPrice" => 0, 
     "StarLevel" => 0, 
     "AvailableOnly" => "false", 
     "PropertyType" => "NotSet", 
     "ExactDestination" => "false" 
    ); 

Это сохранит два элемента массива RoomInfo.

Смежные вопросы