Loop through an XML object with SimpleXML

SimpleXML doesn't have a getElementsByTagName() method (DOMDocument does).

In SimpleXML, the object (e.g $xml) is treated as the root element. So you can loop through the product items like so:

$xml = simplexml_load_string($xmlString);
foreach($xml->products->item as $item)
{
    echo (string)$item->product_id;
    echo (string)$item->model;
}

Example of building a devices associative array:

$devices = array();

$xml = simplexml_load_string($xmlString);
foreach($xml->products->item as $item)
{
   $device = array();

   foreach($item as $key => $value)
   {
        $device[(string)$key] = (string)$value;
   }

   $devices[] = $device;
}

print_r($devices);

Outputs:

Array
(
    [0] => Array
        (
            [product_id] => 32417
            [manufacturer] => Alcatel
            [model] => Sparq 2
            [deeplink] => http://www.mysite.com/sc_offer?gid=32417
            [thumbnail_URL] => http://www.mysite.com/images/devices/thumbs/Alcatel-Sparq-II.jpg
            [image_URL] => http://www.mysite.com/images/devices/Alcatel-Sparq-II.jpg
            [price_not_working] => 0.00
            [price_poor] => 0.00
            [price_fair] => 20.00
            [price_good] => 25.00
            [price_perfect] => 25.00
            [price_new] => 25.00
            [battery_new] => 1.00
            [battery_perfect] => 1.00
            [battery_good] => 1.00
            [battery_fair] => 1.00
            [battery_poor] => 0.00
            [charger_new] => 1.00
            [charger_perfect] => 1.00
            [charger_good] => 1.00
            [charger_fair] => 1.00
            [charger_poor] => 0.00
            [packaging_new] => 1.00
            [packaging_perfect] => 1.00
            [packaging_good] => 1.00
            [packaging_fair] => 1.00
            [packaging_poor] => 0.00
        )

    [1] => Array
        (
            [product_id] => 31303
            [manufacturer] => Apple
            [model] => iPhone 3G 8gb
            [deeplink] => http://www.mysite.com/sc_offer?gid=31303
            [thumbnail_URL] => http://www.mysite.com/images/devices/thumbs/iPhone 8 3G.jpg
            [image_URL] => http://www.mysite.com/images/devices/iPhone 8 3G.jpg
            [price_not_working] => 0.00
            [price_poor] => 0.00
            [price_fair] => 7.00
            [price_good] => 2.00
            [price_perfect] => 2.00
            [price_new] => 2.00
            [battery_new] => 1.00
            [battery_perfect] => 1.00
            [battery_good] => 1.00
            [battery_fair] => 1.00
            [battery_poor] => 0.00
            [charger_new] => 1.00
            [charger_perfect] => 1.00
            [charger_good] => 1.00
            [charger_fair] => 1.00
            [charger_poor] => 0.00
            [packaging_new] => 1.00
            [packaging_perfect] => 1.00
            [packaging_good] => 1.00
            [packaging_fair] => 1.00
            [packaging_poor] => 0.00
        )

)

I don't want to spoil the existing answer as it is answering correct an in a general fashion.

For your concrete requirements as with your XML there aren't any attributes and you're just looking for the element-name => node-value pairs here, there is one function that comes to mind in conjunction with SimpleXMLElement here: get_object_vars.

It is useful whenever you convert an object into an array and as SimpleXMLElement turns element names into object property names and the node-values as those property values it's pretty straight forward here:

$xml     = simplexml_load_string($buffer);

$items   = $xml->products->item;

$devices = array_map('get_object_vars', iterator_to_array($items, FALSE));

print_r($devices);

The output is as suggested in the existing answer. And the online demo is here: https://3v4l.org/iQKQP

You will likely able to achieve similar results with casting to arrays (if not exactly the same with SimpleXML), however in this case as I wanted to map it, I needed a true function.

There is also the json-en- and -de-code doubling for converting complete trees, which comes in handy here, too:

$xml     = simplexml_load_string($buffer);

$items   = $xml->products;

$devices = json_decode(json_encode($items), TRUE)['item'];

The output then again is exactly as the existing answer. And the online demo again is here: https://3v4l.org/ToWOs

Hope this is helpful and widens the view a bit.

Tags:

Php

Xml

Simplexml