I am having trouble on my php simple xml object.
I have the following xml data in my log
SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => test
[scanner] => Data
[id] => WordData
[position] => 1800
[error] => false
[num] => 6
)
[subpod] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => Surnames
)
[plaintext] => Common (US population: 650 people, white: 63% | black: 35%)
[img] => SimpleXMLElement Object
(
[#attributes] => Array
(
[alt] => Common (US population: 650 people, white: 63% | black: 35%)
[title] => Common (US population: 650 people, white: 63% | black: 35%)
[width] => 349
[height] => 18
)
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => Cities
)
[plaintext] => Littleton Common (Massachusetts, 2789 people)
[img] => SimpleXMLElement Object
(
[#attributes] => Array
(
[alt] => Littleton Common (Massachusetts, 2789 people)
[title] => Littleton Common (Massachusetts, 2789 people)
[width] => 287
[height] => 18
)
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => Buildings
)
[plaintext] => Rotunda on Woolwich Common (London, Greater London)
[img] => SimpleXMLElement Object
(
[#attributes] => Array
(
[alt] => Rotunda on Woolwich Common (London, Greater London)
[title] => Rotunda on Woolwich Common (London, Greater London)
[width] => 356
[height] => 18
)
)
)
.....more simpleXmlElement object
)
)
my php varible $xmlObj = SimpleXMLElement Object but when I have the following
if (is_array($xmlObj->subpod)){
echo 'is array';
}else {
echo 'not array';
}
the output is always 'not array' and I want my codes to echo 'is array'
I thought $xmlObj->subpod is an array.
When I test $xmlObj->subpod[0]->plaintext, it will actually return strings.
I am not sure how to solve this problem. Can anyone help?
If you were to var_dump($xmlObj->subpod), you would see that it is still a SimpleXMLElement object. However, it can still be called as if it were an array. (See the note after this example, which hints that the class implements ArrayAccess, even though the class documentation doesn't.)
The correct way to check for this structure would be using SimpleXMLElement::count():
if ($xmlObj->subpod->count() > 0) { ... }
Edit: The output in your question is presumably from print_r, which is sometimes rather unhelpful in its output (e.g. telling you something is an array when it's not). Try using var_dump instead, as it's generally more useful for debugging. The only caveat here is that you don't get to see the entire nested object structure for SimpleXMLElement objects!
Inside SimpleXMLElement Object everything is SimpleXMLElement Object, print_r and var_dump sometimes lie about arrays -they are traversable objects, but you can perform most operations on them as if they were arrays. If you insist on having pure array, you can cast this node to array:
$subpod = (array)$xmlObj->subpod;
Related
When looping through the below xml object, I need to get the data out of each attribute, and if attributes dont exist, move on. I am not sure how to check to see if #attributes even exists. Currently, if it doesn't my loop dies.
I have tried:
if(isset($v[0]->user->attributes())){
....
but that gives me a php error:
Cannot use isset() on the result of an expression (you can use "null !== expression" instead)
So I am not sure how to check if it exist, if it does i can run through the loop. if it doesnt i can move on...
[server] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 17980
)
[user] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 1075159
[default-loc] => 50000
[status] => 1
[license] => high,standard
[password] => aebecf880f2060c31e44f820785e0aa63ea4cc44
[primary] => 50000
[username] => 17980_50000
)
[description] => Customer X
)
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 14642
)
[user] => Array
(
[0] => SimpleXMLElement Object
(
[description] => Customer Y
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 24151
)
[user] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 1075159
[default-loc] => 50000
[status] => 1
[license] => high,low
[password] => aebecf880f2060c31e44f820785e0aa63ea4cc44
[primary] => 51412
[username] => 17980_51412
)
[description] => Customer Z
)
)
)
)
I am not sure how much this will help you, but when trying to iterate through an XML. I find its best to use recursion instead of looping. Your question doesn't show if you are using a recursive function or a loop but you do say "When looping through..."
If you solve this recursively, you can simply stop and perform your required operation whenever you detect you are at a leaf node that is of type attribute.
This should eliminate any potential null pointer exceptions you may encounter when simply "looping" through the XML.
I have a scenario where an API is returning multiple records inside object containing a numeric array like so;
stdClass Object
(
[Event] => Array
(
[0] => stdClass Object
(
[ID] => 111
[Name] => My First Event
[EventType] => stdClass Object
(
[ID] => 1
[Category] => Music
)
)
[1] => stdClass Object
(
[ID] => 222
[Name] => My Second Event
[EventType] => stdClass Object
(
[ID] => 2
[Category] => Sport
)
)
)
[Errors] => stdClass Object
(
[Result] => 0
[Message] =>
)
[RecordCount] => 2
)
I'm current using a foreach loop to iterate through the records. This works fine.
foreach($result->Event as $Event)
But there is a problem here I have a scenario where a single results is returned in the object like so;
stdClass Object
(
[Event] => stdClass Object
(
[ID] => 11
[Name] => My Only Event
[EventType] => stdClass Object
(
[ID] => 2
[Category] => Sport
)
)
[Errors] => stdClass Object
(
[Result] => 0
[Message] =>
)
[RecordCount] => 1
)
Notice there is no [0] array index for the single results.
What's the best way to overcome this keeping in mind that I have no control of the data returned by the API?
Check if Event is an array or an object
if( is_object( $result->Event ) )
{
// ...
}
else
{
foreach( // [....]
}
You may process the object or overwrite it with a 1 item array as suggested by Sam
Btw: very bad API design. I would complain....
The best workaround I have found is to add the single Event to an array with a zero index within the result object. This way the result object matches the same structure as a result containing multiple records.
if(!is_array($result->Event)){
$result->Event = array($result->Event);
}
I have a JSON array that I want to be able to drill down to a lower level and print just that value. The problem occurs when I reach a level that has is indacted as [0] (or [n]). For example I have the following output, and I want to just print the game key for the first league.
This is how I am trying to print it
HtmlSpecialChars(print_r($user->fantasy_content->users[0]->user[1]->games[0]->game[0]->game_key,1))
However I keep getting this error:
Cannot use object of type stdClass as array
When I do it incrementally it seems to fail on this command (so I assume I'm not index correctly):
$user->fantasy_content->users[0]
Here is the output:
stdClass Object
(
[fantasy_content] => stdClass Object
(
[xml:lang] => en-US
[yahoo:uri] => /fantasy/v2/users;use_login=1/games
[users] => stdClass Object
(
[0] => stdClass Object
(
[user] => Array
(
[0] => stdClass Object
(
[guid] => IYEZUHTVBYRLIB3OAQC5WRZPQY
)
[1] => stdClass Object
(
[games] => stdClass Object
(
[0] => stdClass Object
(
[game] => Array
(
[0] => stdClass Object
(
[game_key] => 147
[game_id] => 147
[name] => Baseball
[code] => mlb
[type] => full
[url] => http://baseball.fantasysports.yahoo.com/b1
[season] => 2006
)
)
)
[count] => 1
)
)
)
)
[count] => 1
)
[time] => 52.390813827515ms
[copyright] => Data provided by Yahoo! and STATS, LLC
[refresh_rate] => 60
)
)
For objects you must use the -> syntax and if the key/property name is a number or has other special characters, you will need to use the $object->{'0'} syntax.
The game_key can be retrieved using:
$user->fantasy_content->users->{'0'}->user[1]->games->{'0'}->game[0]->game_key;
You can convert a stdClass object to an array by casting it like so:
<?php
$array = (array) $myObject;
echo json_encode($array);
You can also cast inline:
<?php
echo json_encode((array) $object);
I have a simpleXML output of:
SimpleXMLElement Object
(
[#attributes] => Array
(
[version] => 2
)
[currentTime] => 2013-02-05 21:26:09
[result] => SimpleXMLElement Object
(
[rowset] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => characters
[key] => characterID
[columns] => name,characterID,corporationName,corporationID
)
[row] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Wrytha Cy
[characterID] => 209668693
[corporationName] => Deep Core Mining Inc.
[corporationID] => 1000006
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Eve Mae
[characterID] => 624980803
[corporationName] => Viziam
[corporationID] => 1000066
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Wrytha
[characterID] => 709227913
[corporationName] => The Flying Tigers
[corporationID] => 669350666
)
)
)
)
)
[cachedUntil] => 2013-02-05 21:35:04
)
I would like to loop through with my php loop and get "name' and "characterID". I've trying something like:
$simpleXML = simplexml_load_string($xml);
foreach ($simpleXML->result->rowset->row as $row) {
print_r($row);
$name = $row['#attributes']['name'];
echo $name.'<br>';
}
but $name is not being set. It's gonna be something simple, just not seeing it in my haste and first time with simpleXML.
Attributes are accessed using the syntax $element['attribute_name'], so in your case, you need $row['name'].
It's important to remember that SimpleXML objects are kind of magic - the $element->child, $element_list[0] and $element['foo'] syntax overloads the normal PHP logic to be useful. Similarly, (string)$element will give you the full textual content of an element, however it is broken up in the actual XML.
As such, the print_r output will not give you a "real" view of the object, so should be used with care. There are a couple of alternative debug functions I've written here which give a more accurate idea of how the object will behave.
It's pretty straightforward, I have an array with a number of nodes of the same structure available as Simple XML objects (extracted from different XML documents). What's the easiest way to add them to a single XML document, so I can output the combined XML? I've searched, but I can't find a good solution.
Edit: Array looks like this, how do I combine these objects in one single XML object?
Array (
[0] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[no] => 23432423
[type] => Array
)
[id] => 40043030
[title] => Cars
[cinemadate] => 2011-07-06
[changedate] => 2011-07-27T10:19:00
[year] => 2011
[length] => 112
[genres] => SimpleXMLElement Object
(
[genre] => animatie
)
[1] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[no] => 48050593
[type] => Array
)
[id] => 1231676
[title] => Arrietty
[cinemadate] => 2011-07-06
[changedate] => 2011-06-21T10:39:00
[genres] => SimpleXMLElement Object
(
[genre] => animatie
)
Iterate over the array and add the data to the existing simplexml object. You have not provided much information in your question how the array data looks like nor have you provided an example simplexml object / xml chunk, so there is not much more to say specifically.