SimpleXML Iterating Issues And Arrays

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
linchatter
Forum Newbie
Posts: 5
Joined: Fri Oct 08, 2010 8:17 am

SimpleXML Iterating Issues And Arrays

Post by linchatter »

Example

Code: Select all

<root>
   <dog>a</dog>
   <cat>b</cat>
   <Shelter>North</Shelter>
    <Shelter>South</Shelter>
</root>

$obj = simplexml_load_string($XML_ABOVE);

foreach($obj as $key=>$val)
{
print (string)$val;
}

The above will print dog, cat, shelter, shelter

What I need to do, is when an array is encountered (shelter) run it again.

Problem is, the current routine treats this as 4 items instead of 3 (dog, cat, shelter (array)). If I do $val->count everything is showing up as 0. How can I iterate through this and then check if shelter is an array and run it again.

I know how to do it :), just need it as guess to act more like an array. So the foreach products 3 items, I can then look at each item, if the item is an array, run it again.
User avatar
twinedev
Forum Regular
Posts: 984
Joined: Tue Sep 28, 2010 11:41 am
Location: Columbus, Ohio

Re: SimpleXML Iterating Issues And Arrays

Post by twinedev »

If it is not going any other levels in, you could use:

Code: Select all

foreach($obj as $key=>$val) {
	if (is_array($val)) {
		foreach($val as $item) {
			echo $item;
		}
	}
	else {
		echo $val;
	}
}
linchatter
Forum Newbie
Posts: 5
Joined: Fri Oct 08, 2010 8:17 am

Re: SimpleXML Iterating Issues And Arrays

Post by linchatter »

That does not work. It sees each item while iterating as a unique XMLSimple object, not as an array.
<info>
<dog>ddd</dog>
<cat>ddd</cat>
<location>ddd</location>
<location>ddd</location>
</info>

If you were to do print_r($obj) on the above then it would show a normal array. But when it iterates it treats it diff.

print_r(would give)
[dog]
[cat]
[array]
location [0]
location [1]

But when iterating over the object, it is going over it 4 times instead of 3, because it is treating location as unique elements. Wierd little gotchya

foreach($obj as $key=>$val) {

Ech $val is an object, not an array.
User avatar
ok
Forum Contributor
Posts: 393
Joined: Wed May 31, 2006 9:20 am
Location: The Holy Land

Re: SimpleXML Iterating Issues And Arrays

Post by ok »

Well, it seems that the way SimpleXML treats your XML file makes sense, because you have just 4 elements which all of them are placed under root.

You can force SimpleXML to give you the same array as shown when using var_dump.

Let's say you have the following XML file:

Code: Select all

<root>
   <dog>a</dog>
   <cat>b</cat>
   <Shelter>North</Shelter>
   <Shelter>South</Shelter>
</root>
Using the following code:

Code: Select all

// Where $xml contains the above XML file
$obj = simplexml_load_string($xml);
var_dump($obj);
produces the output:
[text]
object(SimpleXMLElement)#1 (3) {
["dog"]=>
string(1) "a"
["cat"]=>
string(1) "b"
["Shelter"]=>
array(2) {
[0]=>
string(5) "North"
[1]=>
string(5) "South"
}
}
[/text]

However, using foreach on $obj doesn't work, as you said. The solution is to use casting:

Code: Select all

$arr = (array) $obj;
foreach ($arr as $key => $value) {
    var_dump($key);
    var_dump($value);
}
The above will output:
[text]
string(3) "dog"
string(1) "a"
string(3) "cat"
string(1) "b"
string(7) "Shelter"
array(2) {
[0]=>
string(5) "North"
[1]=>
string(5) "South"
}
[/text]
Post Reply