Why does SimpleXML change my array to the first element of the array when I use it?

Here is my code:

$string = <<<XML <?xml version='1.0'?> <test> <testing> <lol>hello</lol> <lol>there</lol> </testing> </test> XML; $xml = simplexml_load_string($string); echo "All of the XML:\n"; print_r $xml; echo "\n\nJust the 'lol' array:"; print_r $xml->testing->lol; 

Output:

 All of the XML: SimpleXMLElement Object ( [testing] => SimpleXMLElement Object ( [lol] => Array ( [0] => hello [1] => there ) ) ) Just the 'lol' array: SimpleXMLElement Object ( [0] => hello ) 

Why does it only print [0] instead of the whole array? I do not understand.

+8
object arrays php simplexml
source share
5 answers

This is because you have two lol elements. To access the second, you need to do this:

 $xml->testing->lol[1]; 

it will give you "there"

 $xml->testing->lol[0]; 

Gives you hello

The children () method of the SimpleXMLElement element will provide you with an object containing all the children of the element, for example:

 $xml->testing->children(); 

will provide you with an object containing all the children of the SimpleXMLElement test element.

If you need iteration, you can use the following code:

 foreach($xml->testing->children() as $ele) { var_dump($ele); } 

More information about SimpleXMLElement can be found here:

http://www.php.net/manual/en/class.simplexmlelement.php

+5
source share

What @Yottatron offers is true, but not all cases, as this example shows:

if your XML looks like this:

 <?xml version='1.0'?> <testing> <lol> <lolelem>Lol1</lolelem> <lolelem>Lol2</lolelem> <notlol>NotLol1</lolelem> <notlol>NotLol1</lolelem> </lol> </testing> 

The output of Simplexml will be:

 SimpleXMLElement Object ( [lol] => SimpleXMLElement Object ( [lolelem] => Array ( [0] => Lol1 [1] => Lol2 ) [notlol] => Array ( [0] => NotLol1 [1] => NotLol1 ) ) ) 

and writing

 $xml->lol->lolelem 

you expect your result to be

 Array ( [0] => Lol1 [1] => Lol2 ) 

but instead you get:

 SimpleXMLElement Object ( [0] => Lol1 ) 

and

 $xml->lol->children() 

You'll get:

 SimpleXMLElement Object ( [lolelem] => Array ( [0] => Lol1 [1] => Lol2 ) [notlol] => Array ( [0] => NotLol1 [1] => NotLol1 ) ) 

What you need to do if you want only lolelema:

 $xml->xpath("//lol/lolelem") 

This gives this result (not as the expected form, but contains the correct elements)

 Array ( [0] => SimpleXMLElement Object ( [0] => Lol1 ) [1] => SimpleXMLElement Object ( [0] => Lol2 ) ) 
+6
source share

what you might want to do is use Json encode / decode

 $jsonArray = Json_decode(Json_encode($xml), true); 

With a true argument, you can call instead use → use [name]

thus an example:

 $xml = file("someXmlFile.xml"); $jsonArray = Json_decode(Json_encode($xml), true); foreach(jsonArray['title'] as $title){ Do something with $titles } 

If you have more than one element, it will typically be placed in @attributes if the elements have attributes. This can be contrasted: $title = $title['@attributes']

Hope this helps.

+1
source share

Oh yes, I remember how simple XML almost dealt with this parsing arrays problem. Try the code below. It will provide you with an array of LOL elements or, if you have only one LOL element, it will also return this to the array.

The main advantage of this is that you can do something like foreach ($ lol as $ element), and it will still work on one (or 0) LOL element.

 <?php $string = <<<XML <?xml version='1.0'?> <test> <testing> <lol>hello</lol> <lol>there</lol> </testing> </test> XML; $xml = simplexml_load_string($string); echo "<pre>"; echo "All of the XML:\n"; print_r($xml); echo "\n\nJust the 'lol' array:\n"; $test_lols = $xml->testing->children(); $childcount = count($test_lols); if ($childcount < 2) { $lol = array($test_lols->lol); } else { $lol = (array) $test_lols; $lol = $lol['lol']; } print_r($lol); ?> 
+1
source share

This is the problem ...

Xpath can be a little slow, so you can achieve the same effect with a simple loop.

 for ($i = 0; $i < count($xml->testing->lol); $i++) { print_r($xml->testing->lol[$i]); } 
0
source share

All Articles