7

Please read the bolded line below before you comment that this may be a duplicate. This has nothing to do with SimpleXML.

Let me start off by showing how the XML should be laid out. Please ignore the namespaces:

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

Notice under hot1:RoomsInformation there is RoomInfo. I'm supposed to be able to send multiple RoomInfo nodes. But I'm using a PHP class to convert an array to this object to be submitted via SOAP.

Here's my array before it gets converted to an object:

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

The problem is that after converting to an Object, there is only 1 RoomInfo and its the last one. My thought is because the RoomsInformation array has 2 identical KEY names. So how can I make this work?

For your information, here is the SOAP class I use and the arrayToObject function:

http://pastebin.com/SBUN0FAF

10
  • 3
    possible duplicate of How to convert array to SimpleXML Commented Jul 2, 2013 at 14:31
  • 1
    If you use SOAP, then the php built-in SoapClient can handle the array Commented Jul 2, 2013 at 14:33
  • 2
    You can't, not with that array. No matter how many RoomsInformation entries you have, if they have the same key they are indeed just one. Commented Jul 2, 2013 at 14:54
  • Another portential related question is: How to update SimpleXMLElement using array Commented Jul 3, 2013 at 4:10
  • Thanks for pointing out the duplicates. However I've already looked at those and they didnt have to do with what I'm trying to do. I'm not trying to use SimpleXML. I'm trying to convert to an object for use with SOAP Commented Jul 3, 2013 at 13:37

3 Answers 3

14

The problem is, your array is invalid as you suspected because of the duplicate keys. One way to solve the issue is to wrap each "RoomInfo" in its own array like so:

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

And you can generate the XML like this:

// 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");
        }
    }
}

I attribute the array_to_xml function to the wonderful author here: https://stackoverflow.com/a/5965940/2200766

Sign up to request clarification or add additional context in comments.

1 Comment

Not trying to use SimpleXML. I have to convert to an object to send via SOAP Client. Making the changes you suggested makes both RoomsInfo disappear altogether.
0

It looks as though you should have your array like this, instead;

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

This will preserve the two RoomInfo array elements.

Comments

-1

simply use this function, where $data is multideminsional array

function array_to_xml( $data ) {
         $xml_data = new SimpleXMLElement('<?xml version="1.0"?><data></data>');

         foreach( $data as $key => $value ) {
           $node = $xml_data->addChild('row_' . $key);

           foreach( $value as $keyx => $valuex ) {
             $node->addChild($keyx,$valuex);
            }


          }
          return $xml_data->asXML();
     }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.