note 80576 deleted from ref.simplexml by danbrown
| From: | danbrown@php.net | Date: | Mon, 18 May 2009 01:16:06 +0000 |
| Subject: | note 80576 deleted from ref.simplexml by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-155505@lists.php.net to get a copy of this message | ||
Note Submitter: mtudor at N0SPMicefusion dot co dot uk
----
Be careful when trying to access a repeated xml tag such as in the example below:
<?php
$xmlText = "<test>
<group>
<multi>One</multi>
<multi>Two</multi>
</group>
</test>";
$xml = new SimpleXMLElement($xmlText);
?>
SimpleXML will convert this into an object as follows:
SimpleXMLElement Object
(
[group] => SimpleXMLElement Object
(
[multi] => Array
(
[0] => One
[1] => Two
)
)
)
From this, you may think as I did, that the following snippet will yield an Array with two elements:
<?php
print_r($xml->group->multi)
?>
What actually happens is that SimpleXMLElement assumes that you want the first element in the array,
so the above snippet will actually return:
SimpleXMLElement Object
(
[0] => One
)
Accessing using Array notation:
<?php
print_r($xml->group->multi[1]);
?>
Will return:
SimpleXMLElement Object
(
[0] => Two
)
as would be expected. It seems that SimpleXML has a mechanism to determine whether or not you are
using Array notation and if not, returning the first element of the array.
Unfortunately, this is a real problem for using functions such as count() and is_array().
is_array($xml->group->multi) will actually return false, as you are actually testing against
the first element of the multi array, wrapped in a SimpleXMLElement object.
The solution, it would seem, is one of the following:
1. Access the element using xpath, which returns an array that can be counted and edited etc.:
<?php
print_r($xml->group->xpath("multi"));
?>
2. Use isset to detect if array index 1 is present:
<?php
if(isset($xml->group->multi[1]))
{
echo "The XML has more than one multi element";
}
?>
See http://vega.rd.no/article/simplexml-not-that-simple
for further information.
I wonder if it might be worth including this in the body of the documentation, as it is quite a big
gotcha?