Explanation for traversing object variables of simplexml node list - php

I have this
$xml = new SimpleXMLElement($output);
$names = $xml->param->value->array->data;
Here is the output
SimpleXMLElement Object
(
[value] => Array
(
[0] => SimpleXMLElement Object
(
[struct] => SimpleXMLElement Object
(
[member] => SimpleXMLElement Object
(
[name] => school
[value] => SimpleXMLElement Object
(
[struct] => SimpleXMLElement Object
(
[member] => Array
(
[0] => SimpleXMLElement Object
(
[name] => schoolid
[value] => SimpleXMLElement Object
(
[string] => 49961
)
)
[1] => SimpleXMLElement Object
(
[name] => schoolname
[value] => SimpleXMLElement Object
(
[string] => Millersville Elementary School
)
)
I am trying to get to the "schoolname" value
using
for($i=0;$i<count($names);$i++) {
echo $names[0][$i]->struct->member->value->struct->member[0]->value.'<br>';
}
I've also tried as string($names[0]etc.) with no success. I think I am messing up the order in the beginning with $names[0][$i]??
Any help is much appreciated!

Consider learning XPath if you feel lazy. It's the easy way to address your issue if you don't want to loose it with a never ending streak of ->'s :)
Learning XPath is also an investment. When you deal with XML you need to know it. It's the SQL of XML or DOM (see DOMXPath).
I know this is not really an answer but spending some time and what I pointed out here is worth it and will also solve you problem.

Here is the solution using xpath to get fieldname and values
$cols = $xml->xpath('//member/value/struct/member/name');
$names = $xml->xpath('//member/value/struct/member/value/*');
for($i=0;$i<count($cols);$i++) {
echo $cols[$i].' = '.$names[$i].'<br>';
}
xpath is a must for anyone dealing with xml!

The result $name is a mix of valuse (object and array).
Try to convert $name to an object only or an array only.
The example you posted is not complete, could not try to chaqge it.

I recently had a similar issue, I ended up writing something that flattened the whole structure to be arrays within arrays, much more travesrsable, but to the matter at hand, I often find it helpful to var_dump/print_r each stage and build it up level by level.
$names is an object so it would seem to me the reference you want is:
$names->value[0]->struct->member->value->struct->member['value'][1]->value;
Edit: I've ignored the looping part for now as I think you'll need to re-evaluate your count(), it seems it needs to be count($names->value), which is the array of schools if I'm correct, in which case the $i would go in the first [0].

Related

Parsing a timestamp based PHP std class obkect

I have a PHP standard class object converted from json_decode of a REST call on an API which looks like :
Array
(
[1437688713] => stdClass Object
(
[handle] => Keep it logically awesome.
[id] => 377748
[ping] => stdClass Object
(
[url] => https://api.me.com
[id] => 377748
[name] => web
[active] => 1
[events] => Array
(
[0] => data_new
[1] => data_old
)
So far i had no issues in parsing any of the PHP objects. However this one is failing because i can not access the nested object elements using a key since 1437688713 is not assigned to a key and accessing an object is failing if i try to do this:
$object->1437688713->handle
Is there a way to access these elements ?
Update: one more thing, i would never know this value (1437688713) in advance. Just like a key. All i get is a stdclass object which i have to parse.
The outer part of your data is an array, not an object. Try:
$array['1437688713']->handle;
or if you don't know the key, you can iterate over the array (handy if it may contain multiple objects too):
foreach ($array as $key => $object) {
echo $key; // outputs: 1437688713
echo $object->handle; // outputs: Keep it logically awesome.
}
Get the first item from $object array
$first_key = key($object);
Use it with your response array,
$object[$first_key]->handle;
Or, the first element of array
$first_pair = reset($object)->handle;

Sort multidimensional XML with PHP by date

I can't find an exact duplicate of this question, as my nodes are numerical keys.
I need to sort this xml by date - newest first:
[article] => Array
(
[0] => SimpleXMLElement Object
(
[value] => some value
[date] => 2012-08-13 18:54:09
)
[1] => SimpleXMLElement Object
(
[id] => some more value
[date] => 2012-08-09 10:24:06
)
[2] => SimpleXMLElement Object
(
[id] => another value
[date] => 2012-08-11 20:45:44
)
)
How can I best do that - possibly WITHOUT turning the XML into a PHP array and sorting it then.
From your sample, it looks like you have an array of objects already, so usort would work fine.
The callback would look something like this:
function compare_node_dates($a, $b)
{
return
strtotime((string)$b->date)
-
strtotime((string)$a->date);
}
However, if your outermost variable isn't actually an array, there is no way I'm aware of doing this without creating an array, sorting that, and using that to construct brand new XML.

How to access stdclass object after a specific key value pair?

I have a stdclass object as shown below:
stdClass Object
(
[text] => Parent
[values] => Array
(
[0] => stdClass Object
(
[id] => /m/0c02911
[text] => Laurence W. Lane Jr.
[url] => http://www.freebase.com/view/m/0c02911
)
)
)
I iterate over multiple such objects, some of which have
stdClass Object
(
[text] => Named after
[values] => Array
(
[0] => stdClass Object
(
[id] => /m/0c02911
[text] => Stanford
[url] => SomeURL
)
)
)
I was wondering how I would access the "values" object if it comes after a "text" that has "Parent" as its value?
there are serveral ways to turn it to array:
First Solution:
$value = get_object_vars($object);
Second Solution:
$value = (array) $object;
Third Solution
$value = json_decode(json_encode($object), true);
to get value of converted array
echo $value['values']['0']['id'];
The alternate way to access objects var without convert the object, try
$object->values->{'0'}->id
Expanding (or rather minimalizing) upon answer by Somwang Souksavatd, I like accessing Object values like this:
echo get_object_vars($object)['values']['0']['id'];
I had the same issue, still not so sure why but I was able to get it working using this workaround:
$k2 ="1";
$elements = json_decode('{"id":"1","name":"User1"}');
//$elements['id'] == $k2; //****Not Working
$tmp = (object)$elements;
$tmp = $tmp ->id; //****Working
//$tmp =$elements['id'] ; //****Not Working
return $tmp == $k2;
I have to say that sometimes accessing the element as array works and some times not,(On PHP7 it worked for me but on PHP5.6 it didn't).
$elements can be Array to but I chose to demonstrate with json string.
I hope this helps somehow !!!
$Obj=stdClass Object
(
[text] => Named after
[values] => Array
(
[0] => stdClass Object
(
[id] => /m/0c02911
[text] => Stanford
[url] => SomeURL
)
)
)
$Values= $result->values;
$Item = $Values[0];
$id=$Item->id;
$text = $Item->text;
$url=$Item->url;
I'm doing the same thing and all I did was this;
<?php
$stdObject = json_decode($stdClassObject);
print $stdObject->values[0]->id;
this can help you accessing subarrays in php using codeigniter framework
foreach ($cassule['tarefa'][0] as $tarefa => $novo_puto_ultimos_30_dias) {
echo $novo_puto_ultimos_30_dias;
What you are looking for is the Object['values'][0]: 'values' is the keymap just like 'text', and [0] is the index inside that array you wish to access. so if you would like to get the id deep in the nest, you'd have to do something like
Object['values'][0]['id']
or
Object['values'][0]->id
which should give you /m/0c02911. But I have no idea how you are doing your loop, so you will have to adjust it to your needs and place proper variables where they need to go in that code in your loop. Not exactly sure which language you are working with.

Traverse an object's properties with dynamic names

I am trying to get the current trends from the twitter api (but that's sorta irrelevant).
I receive the information as an object. In this situation some of the properties that I need to access, are dates from when the trends were last updated, therefore I can't hard code the property names.
Here's an example incase I didn't explain myself well, which I fear I didn't :(
stdClass Object
(
[2011-03-09 02:45] => Array
(
[0] => stdClass Object
(
[promoted_content] =>
[events] =>
[query] => RIP Mike Starr
[name] => RIP Mike Starr
)
[1] => stdClass Object
(
[promoted_content] =>
[events] =>
[query] => Mac & Cheese
[name] => Mac & Cheese
)
Note: This is not the full object
You can traverse an object's properties using get_object_vars()
$fooBar = new stdClass();
$fooBar->apple = 'red';
$fooBar->pear = 'green';
foreach(get_object_vars($fooBar) as $property => $value) {
echo $property . " = " . $value . "\n";
}
// Output
// apple = red
// pear = green
Are you getting this data as JSON? If so, check out the second argument to json_decode, which lets you get the results back as an associative array instead of as an object. This will let you use the normal loop constructs, like foreach and obtain keys using array_keys.
If you aren't getting this data via JSON, you can consider using Reflection to grab the properties of an object. (edit #2: I'm not sure if this will work on stdClass or not, actually...)

php simple xml element question/bug

I have some xml, lets say <names number="12"></names>
When I run the following:
$simpleXMLElement = new SimpleXMLElement($xml);
pr($simpleXMLElement);
I get the following:
SimpleXMLElement Object
(
[#attributes] => Array
(
[number] => 12
)
[0] =>
)
It throws in that 0 entry. This is weird. I don't know what it's supposed to represent. If I do this instead:
<names number="12"><name first="oliver" /></names>
I get the following output:
SimpleXMLElement Object
(
[#attributes] => Array
(
[number] => 12
)
[name] => SimpleXMLElement Object
(
[#attributes] => Array
(
[first] => oliver
)
)
)
This is as expected (for me at least). Any thoughts/direction?
First: if you don't correctly format your post, the XML will not be displayed. Indent any code with at least 4 spaces.
Secondly, do not expect print_r() or var_dump() to give you an exact representation of a SimpleXMLElement because SimpleXML uses lots of magic, so children and attributes won't necessarily show up in the output.
It seems to be just SimpleXML doing a quick-and-dirty job of parsing the element: Since you have <names></names>, it adds an array inside the element, as expecting elements within it, and when it doesn't find any elements inside the names tags, it leaves an empty array, with the key 0, since it doesn't know what name to give it.
A short tag (<names />) shouldn't generate the empty content. (As weird as that sounds.)

Categories