Page 1 of 1
SimpleXML Iterating Issues And Arrays
Posted: Thu Sep 08, 2011 11:24 am
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.
Re: SimpleXML Iterating Issues And Arrays
Posted: Thu Sep 08, 2011 1:36 pm
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;
}
}
Re: SimpleXML Iterating Issues And Arrays
Posted: Thu Sep 08, 2011 1:46 pm
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.
Re: SimpleXML Iterating Issues And Arrays
Posted: Thu Sep 08, 2011 3:46 pm
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]