Reputation: 1495
I have a PHP script that loads an XML sheet like so:
$feed = 'mydata.xml';
$xml = file_get_contents($feed);
$data = simplexml_load_string($xml);
echo print_r($data);
The result looks like this (although I've chopped a lot out):
SimpleXMLElement Object
(
[merchant] => SimpleXMLElement Object
(
[@attributes] => Array
(
[id] => 1
[name] => companyname
)
[prod] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[id] => 690579815
[lang] => en
[pre_order] => no
[web_offer] => yes
[in_stock] => yes
)
My question is, how can I access the prod array? I want to be able to count it like so:
count($data['prod']);
And also get particular field values but I'm quite new to PHP and XML and can't quite do it.
Thanks!
Upvotes: 0
Views: 765
Reputation: 198217
My question is, how can I access the prod array?
You can't. Because there is no array. But it's okay you ask, it's just print_r
has been fooling you a little. SimpleXMLElement is an object and it can change what will be shown when it gets print_r
'ed and it fakes you some arrays there.
Some basics to the rescue:
$data
represents the document element of the XML you have. In case you're in doubt what's in the XML, instead of print_r
look into $data->asXML()
(if you look through your browser view source or hint the output as plain-text otherwise the browser will hide all tags).
$data['prod']
gives you the attribute named prod on that document element. As there is none, it returns null
:
var_dump($data['prod']); --- NULL
And the count
of NULL
is 0:
var_dump(count(NULL)); --- int(0)
You neither want to look into the document element nor do you want to look-up attributes. You're interested in the child-elements named prod inside the merchant element.
So first obtain the first merchant element:
$merchant = $data->merchant;
You obtain elements with object access, that is with the object operator ->
.
And the get the count of the number of child elements named prod:
var_dump(count($merchant->prod)); --- int(3)
As this shows, I've got three (3) children named prod inside the merchant element represented by $merchant
.
So you don't need any array here, the SimpleXMLElement allows you access to all the XML-elements inside the XML document.
As written earlier, the array brackets are used for array-access. So it looks like an array, but it is actually an object. It has been used to access the attributes. But this is only true, if the key is not a number. If it's a number, it will access the n-th named element:
var_dump($merchant->prod[0]->asXML());
Will give the XML of the first prod element of the merchant element:
string(94) "<prod id="690579815" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #1</prod>"
As it is the first element, you can obtain it's id attribute as well:
var_dump($merchant->prod[0]['id']->asXML());
Which returns exactly that attribute:
string(15) " id="690579815""
But it does not stop here. Each of these SimpleXMLElement objects of XML elements and attributes can be cased to string:
var_dump((string)$merchant->prod[0]); --- string(10) "product #1"
var_dump((string)$merchant->prod[0]['id']); --- string(9) "690579815"
Which is most often the actual information you're looking for. When you use echo
or similar, this string-casting is done automatically btw.
echo $merchant->prod[0]; // prints: "product #1"
Similar to arrays (and object), you can also iterate over each SimpleXMLElement. For example the $merchant
element:
foreach ($merchant as $children)
{
echo $children->asXML(), "\n";
}
Gives:
<merchant id="1" name="companyname">
<prod id="690579815" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #1</prod>
<prod id="250544605" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #2</prod>
<prod id="360355798" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #3</prod>
</merchant>
Which is a single element. So more interesting this is with named child-elements:
foreach ($merchant->prod as $prod)
{
echo $prod->asXML(), "\n";
}
This now gives all children named prod one after the other:
<prod id="690579815" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #1</prod>
<prod id="250544605" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #2</prod>
<prod id="360355798" lang="en" pre_order="no" web_offer="yes" in_stock="yes">product #3</prod>
You find this as well explained in Basic SimpleXML usage in the PHP manual. Consult it as another source.
Just take these rules:
print_r
and var_dump
cheat on you when used with SimpleXMLElementUpvotes: 1
Reputation: 6640
SimpleXMLElement
is an object, so you also need to access them as an object:
print count($data->merchant->prod);
Upvotes: 0
Reputation: 9440
To access it as associative array, do this:
$data = json_decode(json_encode($data), true);
then you can access it like this:
count($data['merchant']['prod'])
Upvotes: 0