Looping Through a Simplexml Object, or Turning the Whole Thing into an Array

Looping through a SimpleXML object, or turning the whole thing into an array

You can use the SimpleXML object (or its properties) in a foreach loop. If you want to loop through all the 'records' something like this can be used to access and display the data:

//Loop through all the members of the Item array 
//(essentially your two database rows).
foreach($SimpleXML->body->QueryWithAttributesResult->Item as $Item){
//Now you can access the 'row' data using $Item in this case
//two elements, a name and an array of key/value pairs
echo $Item->Name;
//Loop through the attribute array to access the 'fields'.
foreach($Item->Attribute as $Attribute){
//Each attribute has two elements, name and value.
echo $Attribute->Name . ": " . $Attribute->Value;
}
}

Note that $Item will be a SimpleXML object, as is $Attribute, so they need to be referenced as objects, not arrays.

While the example code above is looping through the arrays in the SimpleXML object ($SimpleXML->body->QueryWithAttributesResult->Item), you can also loop through a SimpleXML object (say $SimpleXML->body->QueryWithAttributesResult->Item[0]), and that would give you each of the object's properties.

Each child element of a SimpleXML object is an XML entity. If the XML entity (tag) is not unique, then the element is simply an array of SimpleXML objects representing each entity.

If you want, this should create a more common row/fields array from your SimpleXML object (or get you close):

foreach($SimpleXML->body->QueryWithAttributesResult->Item as $Item){
foreach($Item->Attribute as $Attribute){
$rows[$Item->Name][$Attribute->Name] = $Attribute->Value;
}
}

//Now you have an array that looks like:
$rows['message12413344443260']['active'] = 1;
$rows['message12413344443260']['user'] = 'john';
//etc.

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
)

)

Converting a SimpleXML Object to an Array

I found this in the PHP manual comments:

/**
* function xml2array
*
* This function is part of the PHP manual.
*
* The PHP manual text and comments are covered by the Creative Commons
* Attribution 3.0 License, copyright (c) the PHP Documentation Group
*
* @author k dot antczak at livedata dot pl
* @date 2011-04-22 06:08 UTC
* @link http://www.php.net/manual/en/ref.simplexml.php#103617
* @license http://www.php.net/license/index.php#doc-lic
* @license http://creativecommons.org/licenses/by/3.0/
* @license CC-BY-3.0 <http://spdx.org/licenses/CC-BY-3.0>
*/
function xml2array ( $xmlObject, $out = array () )
{
foreach ( (array) $xmlObject as $index => $node )
$out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;

return $out;
}

It could help you. However, if you convert XML to an array you will loose all attributes that might be present, so you cannot go back to XML and get the same XML.

Output of for each loop on SimpleXMLElement Object array, one node further in then outside the loop

You're getting confused on the element selection. To get each <Item>, just use $feedobject->Item.

// select each `<Item>`
foreach ($feedobject->Item as $value) {
echo $value->attributes()->ID;
}

When you use $feedobject->Item[$x] as $value, this already points directly to elements inside <Item> which shows you <ItemField>.

Loop through an object containing an array of objects

This is happening because simpleXML structures are not normal arrays but instead are iterators that do not have an array index.

The solution it to manually maintain your own index.

How to iterate through XML values that are a SimpleXMLElement Object

As you can see in your print_r output, the 'listing' field of the XML-Object is the array, not the title. So what you have to do is iterate through the listings and print out each listings title:

foreach ($xml->listing as $listing)
{
echo $listing->title;
}

To print out the pictures you'd do something like this:

foreach ($xml->listing as $listing)
{
echo "Title: " . $listing->title . "<br>";

foreach ($listing->photos->children() as $child)
{
echo $child . "<br>";
}
}

Unable to iterate of SimpleXMLElement objects and insert into array

And as usual, the "post a question and then figure out the answer" principle is in effect.

The trick was casting the values to string with __toString():

$channel_data = new SimpleXMLElement($channel_xml->data);
foreach ($channel_data->channel as $nb_channel) {
$channel_name = $nb_channel->name->__toString();
$channel_tid = $nb_channel->tid->__toString();
$target_channels[$channel_tid] = $channel_name;
}

Once I did that, my variables has the correct data, and I was able to fill the $target_channels array.

How to Loop through XML subnodes using PHP's simplexml

$hotel_amenities = $xml->contentDataResults->hotelContent->hotelAmenities->children();
foreach($hotel_amenities as $a)
{
echo $a;
}

simplexml objects and arrays within each other

Let's use simplexml along with xpath, see comments inline below

<?php
$xml = simplexml_load_file('xml.xml');

// let's take all the divs that have the class "stff_grid"
$divs = $xml->xpath("//*[@class='stff_grid']");

// for each of these elements, let's print out the value inside the first p tag
foreach($divs as $div){
print $div->p->a . PHP_EOL;

// now for each li tag let's print out the contents inside the a tag
foreach ($div->ul->li as $row){
print " - " . $row->a . PHP_EOL;
}
}
/* this outputs the following
Person 1
- 1 hr
- 2 hr
- 3 hr
- 4 hr
- 5 hr
- 6 hr
- 7 hr
- 8 hr
Person 2
- 1 hr
- 2 hr
- 3 hr
- 4 hr
- 5 hr
- 6 hr
- 7 hr
- 8 hr
Person 3
- 1 hr
- 2 hr
- 3 hr
- 4 hr
- 5 hr
- 6 hr
- 7 hr
- 8 hr
*/


Related Topics



Leave a reply



Submit