Extract data from an XML object - php

How do I extract the data from that XML object, which is a value of a certain array:
Array (
[Title] => SimpleXMLElement Object (
[0] => The Key of Life; A Metaphysical Investigation
)
[ASIN] => SimpleXMLElement Object ( [0] => 0982385099 ) ...
)
I did a foreach of the array like:
foreach ($ArrayName as $FieldLabel => $FieldValue) {
$Variable = $FieldValue[0]....
}
...but still, it gets the whole XML object as the field value. I wanted it to extract the value only not the whole object.

All simple xml objects are iteratable. Basically think of any object as a set, and some set's just happen to contain one object.
To extract your value do this
foreach($title as $item)
{
$list_of_titles = (string) $item;
}
print_r($list_of_titles);
So basically I typecast every item into a string from an object.

Related

Search array of object from JSON data with PHP for a match and then update the matching keys data

I am trying to read a file of JSON data into PHP and search its array or objects for a matching anme value. If a match is found I want to update the content of that array objects data from a form POST data to update the item and then convert back to JSON and save to the json file.
$file = 'plugins.js';
$tmp_json_data = file_get_contents($file);
$data = json_decode($tmp_json_data);
echo '<pre>';
print_r($data);
foreach ($data as $key => $obj) {
echo $obj->name;
echo $obj->url;
echo $obj->tag;
}
Result
Array
(
[0] => stdClass Object
(
[name] => Roundabout - Interactive, turntable-like areas
[url] => http://fredhq.com/projects/roundabout/
[tag] => slide
)
[1] => stdClass Object
(
[name] => Slides - Simple slideshow plugin for jQuery
[url] => http://slidesjs.com/
[tag] => slide
)
)
How can I read my $data array in PHP and search for a matching object name that is equal to $_POST['name'] and if a match is found, update the content of that array object?
I would use an array (an object will work in PHP 7):
$data = json_decode($tmp_json_data, true);
$key = array_search($_POST['name'], array_column($data, 'name'));
Then, I'm not sure what you mean by update, but:
$data[$key]['url'] = 'something new';

simplexml_load_file() does not getting node content

I cannot get XML node contents and attributes at the same time with SimpleXML library:
I have the following XML, and want to get content#name attribute and node's contents:
<page id="id1">
<content name="abc">def</content>
</page>
Method simplexml_load_string()
print_r(simplexml_load_string('<page id="id1"><content name="abc">def</content></page>'));
outputs this:
SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => id1
)
[content] => def
)
As you can see, contents of the content node is present, but attributes are missing. How can I receive the contents and attributes?
Thanks!
The attributes of content are present. This is just a trick of print_r() and how it works with XML objects in memory.
$x = simplexml_load_string('<page id="id1"><content name="abc">def</content></page>');
print_r($x->content);
print_r($x->content['name']);
SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => abc
)
[0] => def
)
SimpleXMLElement Object
(
[0] => abc
)
In simplexml, accessing elements returns SimpleXMLElement objects. You can view the content of these objects using var_dump.
$book=simplexml_load_string('<page id="id1"><content name="abc">def</content></page>');
$content=$book->content;
var_dump($content);
You can access these objects with foreach loop.
foreach($obj as $value) {
if (is_array($value)) {
foreach ($value as $name=>$value) {
print $name.": ".$value."\n";}
}
else print $value;
}
You can not only retrieve contents (such as elements and attributes) but also add and remove them. You can also use Xpath to navigate values in complex XML tree. You just need to go through the methods of SimpleXMLElement class here.
$x = simplexml_load_string('<page id="id1"><content name="abc">def</content></page>');
To get the node's attributes:
$attributes = $x->content->attributes(); //where content is the name of the node
$name = $attributes['name'];
To get the content node's content:
$c = $x->content;
Interesting, that $c can be used as string and as object, i.e.
echo $c; //prints string
print_r($c) //prints it out as object

foreach loop, if this result is same as the last, skip to next that is not the same

i am running a foreach loop to get data from an xml file. the xml file has the same date listed several times, each with different data. what i need to do is show each date only once.
basicly i need the foreach loop to show the first date (object) on the first loop. if the date (object) is the same on the second, third, fourth loop, etc. then skip that loop and move to the next where the date (object) is not the same.
here is what i have now:
$dateResults = $xml->xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]');
foreach ($dateResults as $dateResult) {
print_r($dateResult->date);
echo "<br>";
}
that produces:
SimpleXMLElement Object ( [0] => 02152013 )
SimpleXMLElement Object ( [0] => 02152013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02152013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 )
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02162013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 )
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02172013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02182013 )
SimpleXMLElement Object ( [0] => 02182013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02192013 )
SimpleXMLElement Object ( [0] => 02192013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02202013 )
SimpleXMLElement Object ( [0] => 02202013 ) <-- this one needs to be skipped
SimpleXMLElement Object ( [0] => 02212013 )
SimpleXMLElement Object ( [0] => 02212013 ) <-- this one needs to be skipped
You could try something like putting the date as key and check to see if the date has already been used.
$dateResults = $xml->xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]');
$finalResults = array();
foreach ($dateResults as $dateResult) {
// change your simplexml object to either (int) or (string)
$date = (int) $dateResult->date;
// checks key for repeating date
if (!array_key_exists($date, $finalResults)){
// assuming you want the entire $dateResult match with date as key
$finalResults[$date] = $dateResult
}
}
// to print out the results
foreach ( $finalResult as $result ){
foreach ( $results as $key => $value ){
echo $key." : ".$value;
}
}
// or if you know the date and what you want from that array
echo (string) $finalResult[2152013]['salelink']
Untested, please let me know if theres something not working.
You could add the dates into an array and then check for existence during the loop:
// create array for storing unique dates
$unique_dates = array();
$dateResults = $xml->xpath('/rtnshowtime/filmtitle/show[preceding-sibling::shortname="AGOODDAYTODIEHARD"]');
foreach ($dateResults as $dateResult)
{
// need this to get the time attribute from the object
$time_index = 0;
// if the date does not exist in unique dates array
if ( ! in_array($dateResult->date->$time_index, $unique_dates))
{
// add to unique dates array
$unique_dates[] = $dateResult->date->$time_index;
print_r($dateResult->date);
echo "<br>";
}
}
ok, here's what i have opted for.
$shortname = $_GET['shortname'];
$dateURL = $_GET['date'];
$use_errors = libxml_use_internal_errors(true);
$xml = simplexml_load_file('XML/showtimes.xml');
if (!$xml) {echo "NO XML loaded<br>";}else{echo "XML IS loaded<br>";}
$results = $xml->xpath('/rtnshowtime/filmtitle[child::shortname="'.$shortname.'"]');
foreach ($results as $result) {
echo "showtimes for ".$dateURL."<br>";
foreach ($result->show as $result2) {
if ($result2->date == $dateURL) {
echo " -".$result2->time."- ";
}
}
}
that produces this for example:
showtimes for 02152013
-1300- -1400- -1500- -1600- -1700-
i use $_GET to get the date and shortname from the URL, then i use the shortname to decide which movie inside the xml that i will be dealing with. i then produce that as a result with the first foreach. i then run a second foreach within the first foreach specifically dealing with the child element that contains the dates and times. i then use an if statement to segregate which date i will be dealing with based on the URL. because of that if statement, i can then echo all of the times within that result where the sibling dates are the same. i would like to echo the times such as: 1300, 1400, 1500, 1600 with no comma following the last time, but i dont know how to do that. i tried using implode(), but because each time echo is inside an if statement it's an object instead of array results. i assume that... i'm not extremely familiar with the terminology. i have instead opted for a space and - before each time and a - and space after each time. it will have to work for now. :)
thanks to all of you guys for your assistance! stackoverflow ROCKS!!!

PHP Array get each Key/Value from XML File

I'm getting stumped by simply trying to get the key/value of a certain tier inside an array I have created from an XML file. The part of the array from Print_R() is:
SimpleXMLElement Object
(
Array
(
[category] => SimpleXMLElement Object
(
[#attributes] => Array
(
[settings] => maximum
)
[cat_1] => 5.21
[cat_2] => 5.05
[cat_3] => 19.36
[cat_4] => 21.97
[cat_5] => 12.17
)
)
)
I am trying to get the "cat_1, cat_2, cat_3 .." keys so that I can put them in their own array and use them for other things. I can do print_r($array) and it works, but when I try and do this:
foreach ($array->category as $key => $val) {
$new_array[$key]= "$val";
}
$array->category doesn't seem to target that list. The "SimpleXMLElement Object" from the XML file seems to be in the way of how I normally use arrays. Does anyone know how I can get to those cat_1 ets. lists?
Notice that $array->category is an object, not an array and cat_* are properties. Since they are all public just use:
$new_array = get_object_vars($array->category);
You should convert simpleXML object to array using
$array = json_decode(json_encode((array) $simplexmlob)), 1);
Then use $array['category'] for other things. There is no need to use foreach loop.

Why aren't these values being added to my array as strings?

Further to my question here, I'm actually wondering why I'm not getting strings added to my array with the following code.
I get some HTML from an external source with this:
$doc = new DOMDocument();
#$doc->loadHTML($html);
$xml = #simplexml_import_dom($doc); // just to make xpath more simple
$images = $xml->xpath('//img');
$sources = array();
Here is the images array:
Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[alt] => techcrunch logo
[src] => http://s2.wp.com/wp-content/themes/vip/tctechcrunch/images/logos_small/techcrunch2.png?m=1265111136g
)
)
...
)
Then I added the sources to my array with:
foreach ($images as $i) {
array_push($sources, $i['src']);
}
But when I print the results:
echo "<pre>";
print_r($sources);
die();
I get this:
Array
(
[0] => SimpleXMLElement Object
(
[0] => http://www.domain.com/someimages.jpg
)
...
)
Why isn't $i['src'] treated as a string? Isn't the original [src] element noted where I print $images a string inside there?
To put it another way $images[0] is a SimpleXMLElement, I understand that. But why is the 'src' attribute of THAT object not being but into $sources as a string when I reference it as $i['src']?
Why isn't $i['src'] treated as a string?
Becaue it isn't one - it's a SimpleXMLElement object that gets cast to a string if used in a string context, but it still remains a SimpleXMLElement at heart.
To make it a real string, force cast it:
array_push($sources, (string) $i['src']);
Because SimpleXMLElement::xpath() (quoting) :
Returns an array of SimpleXMLElement
objects
and not an array of strings.
So, the items of your $images array are SimpleXMLElement objects, and not strings -- which is why you have to cast them to strings, if you want strings.

Categories