Extracting information from an XML php gives me error - php

I need to extract information from an XML Radionomy (radio streaming) containing information of artist, title, cover art, weather etc.
By placing this url in the browser goes all information xml:
http://api.radionomy.com/currentsong.cfm?radiouid=ce5b70e5-dcc3-40a2-81b2-c713a02daf29&apikey=842650d9-c21a-474d-be8f-f44413dfaae2&callmeback=no&type=xml&cover=yes&previ%20ous=no
<tracks>
<radioname>RTFM</radioname>
<rank>2</rank>
<isradionomy>1</isradionomy>
<radurl>http://www.radionomy.com/rtfm</radurl>
<track>
<uniqueid>2905480252</uniqueid>
<title>02-13-2016</title>
<artists>News - US</artists>
<starttime>2016-02-14 00:59:57.177</starttime>
<playduration>121352</playduration>
<current>1</current>
</track>
</tracks>
But to try to get information through php gives me error. I do not know where he might be the problem, see if I can lend a hand.
I'm trying this:
$xml = #simplexml_load_file("
http://api.radionomy.com/currentsong.cfm?radiouid=ce5b70e5-dcc3-40a2-81b2-c713a02daf29&apikey=842650d9-c21a-474d-be8f-f44413dfaae2&callmeback=no&type=xml&cover=yes&previ%20ous=no");
if($xml){
foreach ($xml as $track){
$artiste = $track->artists;
$titre = $track->title;
$pochette = $track->cover;
continue;
}
}else{
echo "error";
}
Warning: Invalid argument supplied for foreach() in...

EDIT:
Noticed more mistakes and provided working code.
Use urlencode to encode your URL string. Use $xml->track to loop track nodes.
And stop using # to see the actual errors. It is really helpful to see errors.
Didn't touch your original code but you can take it from here.
<?php
$xml = simplexml_load_file(urlencode("http://api.radionomy.com/currentsong.cfm?radiouid=ce5b70e5-dcc3-40a2-81b2-c713a02daf29&apikey=842650d9-c21a-474d-be8f-f44413dfaae2&callmeback=no&type=xml&cover=yes&previ%20ous=no"));
if($xml){
foreach ($xml->track as $track){
$artiste = $track->artists;
$titre = $track->title;
$pochette = $track->cover;
continue;
}
} else {
echo "error";
}

Related

Parsing Youtube Annotations XML with PHP

While parsing XML with php is not exactly a new topic, I have had problems ensuring I parse Annotations from Youtube due to the varying information coming back.
I have spent quite a lot of time reading up about iterating over the attributes (which I think would be the "safe way") but, unfortunately, I have been unsuccessful with my attempts.
Iterating:
$data = file_get_contents("https://www.youtube.com/annotations_invideo?video_id=GUmcQuJVCrI");
$xml = simplexml_load_string($data);
foreach($xml->children() as $child) {
$role = $child->attributes();
foreach($child as $key => $value) {
if($role == "annotation")
echo "Role:".$role. "<br />";
echo("[".$key ."] ".$value . "<br />");
}
}
Another way I have tried to parse the information is by actually following the paths of the nested elements for example:
$data = file_get_contents("https://www.youtube.com/annotations_invideo?video_id=tFYaQwYbvxg");
$xml = simplexml_load_string($data);
$xml = $xml->annotations[0];
Then with a foreach loop:
foreach($xml->annotation as $annotation) {
I have been able to retrieve some of the information I require
$startX = ($annotation->segment->movingRegion->rectRegion[0]->attributes()->x[0]);
$endX = ($annotation->segment->movingRegion->rectRegion[1]->attributes()->x[0]);
$startY = ($annotation->segment->movingRegion->rectRegion[0]->attributes()->y[0]);
$endY = ($annotation->segment->movingRegion->rectRegion[1]->attributes()->y[0]);
$startW = ($annotation->segment->movingRegion->rectRegion[0]->attributes()->w[0]);
$endW = ($annotation->segment->movingRegion->rectRegion[1]->attributes()->w[0]);
$startH = ($annotation->segment->movingRegion->rectRegion[0]->attributes()->h[0]);
$endH = ($annotation->segment->movingRegion->rectRegion[1]->attributes()->h[0]);
$startT = ($annotation->segment->movingRegion->rectRegion[0]->attributes()->t[0]);
$endT = ($annotation->segment->movingRegion->rectRegion[1]->attributes()->t[0]);
I am well aware this is very messy and it fails if the data is anyway different or if there is an annotation type that I didnt know about.
I have been able to stop it failing for example type "text" annotations by ignoring some annotation types like so...
$type = $annotation->attributes()->type;
if (($type !="promotion") &&($type !="branding") &&($type !="card")&&($type !="drawer"))
but this is not really what I want to do in the long run, i really need to be able to parse all types even if Youtube had a new type tomorrow!
Summary:
I really need a safe, reliable way to be able to retrieve all annotations from any Youtube video and store all the information about each one such as the position X and Y, the start time and end time, the text if exists, the link if exists.
I also need the styling if exists.
If exists is the main problem here I think!
I have it working well for some annotations but not all....
I would appreciate if someone could advise me how to better format this so it is reliable and efficient.
Thanks for your time.

PHP Simplexml traversal

I am trying to traverse this xml feed:
http://www.goonersworld.co.uk/forum/feed.php
using this code:
$data = file_get_contents('http://www.goonersworld.co.uk/forum/feed.php');
//$data = str_replace("content:encoded>","content>",$data);
$xml = simplexml_load_string($data,'SimpleXMLElement', LIBXML_NOCDATA);
foreach ($xml->feed->entry as $stories) {
echo $stories->published."<br>";
}
But I'm getting nothing back. To me it looks like $xml->feed->entry->published but am I missing something?
Ok, so I've figured this out. In case it helps anyone else it was a feed generated by PHPBB (Bulletin Board).
The actual structure I was looking for was simply:
foreach ($xml->entry as $stories) {
echo $stories->published."<br>";
}
feed and entry didn't look to be at the same level in the XML formatting but they were :-(

Read an XML style file using PHP

I am trying to retrieve data from this XML style file :
<Product_Group>
<Product_Group_ID>131</Product_Group_ID>
<Product_Group_Title>Thanks for the Memories</Product_Group_Title>
<Products>
<On_Sale_Date>03/01/12 00:00:00.000</On_Sale_Date>
<ISBN>9780007233694</ISBN>
<Title>Thanks for the Memories</Title>
<Format>Paperback</Format>
<Sub_Format/>
<CoverImageURL_Small>http://www.harpercollins.com/harperimages/isbn/small/4/9780007233694.jpg</CoverImageURL_Small>
</Products>
</Product_Group>
I am using following code but this seems to retrieve nothing. any help in fixing this issues would be highly appreciated
$xml = simplexml_load_string($response);
//$xml= $response;
$updates = array();
//loop through all the entry(s) in the feed
for ($i=0; $i<count($xml->Product_Group); $i++)
{
//get the id from entry
$ISBN = $xml->entry[$i]->ISBN;
//get the account link
$Title = $xml->entry[$i]->Title;
//get the tweet
$Product_Group_SEO_Copy = $xml->entry[$i]->Product_Group_SEO_Copy;
}
1) It is not valid XML. What warnings do you see? You'll need to fix them for simplexml_load_string to work properly.
For example, </CoverImageURL_Small> should be <CoverImageURL_Small/>
2) Assuming that Product_Group is not your actual document root (if it is than $xml points to it already and $xml->Product_Group will not work) then you can access each element like
$xml->Product_Group->Products[$i]->ISBN;
3) It's usually simpler to use a foreach loop than a for loop when dealing with simplexml
foreach($xml->Product_Group->Products as $p)
{
$ISBN = $p->ISBN;
//var_dump($ISBN);
}

Fetch XML data from Steam API gamestats

I Google'd not long ago and came across this solution to loop out information from a XML page.
$url = 'http://steamcommunity.com/id/ChetFaliszek/stats/L4D/?xml=1';
$achxml = simplexml_load_file($url);
foreach ($achxml->playerstats->game as $ach)
{
$name = (string) $ach->NAME;
echo $name. "<br>";
}
I think these lines of code will do the trick but I only get following error when I try to fetch the information: Warning: Invalid argument supplied for foreach() in .... The link to the XML page (random guys XML) is in the $url parameter.
Now to the question: How do I fix this problem so I can see if this code will work?
Thanks in advance.
One more problem before I have fix this issue :) How do I list every achievement that's in the XML page?
try:
foreach ($achxml->achievements->achievement as $achievement)
{
echo $achievement->name, '(closed: ', (string) $achievement['closed'], ')';
}

Parsing XML with PHP (simplexml)

Firstly, may I point out that I am a newcomer to all things PHP so apologies if anything here is unclear and I'm afraid the more layman the response the better. I've been having real trouble parsing an xml file in to php to then populate an HTML table for my website. At the moment, I have been able to get the full xml feed in to a string which I can then echo and view and all seems well. I then thought I would be able to use simplexml to pick out specific elements and print their content but have been unable to do this.
The xml feed will be constantly changing (structure remaining the same) and is in compressed format. From various sources I've identified the following commands to get my feed in to the right format within a string although I am still unable to print specific elements. I've tried every combination without any luck and suspect I may be barking up the wrong tree. Could someone please point me in the right direction?!
$file = fopen("compress.zlib://$url", 'r');
$xmlstr = file_get_contents($url);
$xml = new SimpleXMLElement($url,null,true);
foreach($xml as $name) {
echo "{$name->awCat}\r\n";
}
Many, many thanks in advance,
Chris
PS The actual feed
Since no one followed my closevote, I think I can just as well put my own comments as an answer:
First of all, SimpleXml can load URIs directly and it can do so with stream wrappers, so your three calls in the beginning can be shortened to (note that you are not using $file at all)
$merchantProductFeed = new SimpleXMLElement("compress.zlib://$url", null, TRUE);
To get the values you can either use the implicit SimpleXml API and drill down to the wanted elements (like shown multiple times elsewhere on the site):
foreach ($merchantProductFeed->merchant->prod as $prod) {
echo $prod->cat->awCat , PHP_EOL;
}
or you can use an XPath query to get at the wanted elements directly
$xml = new SimpleXMLElement("compress.zlib://$url", null, TRUE);
foreach ($xml->xpath('/merchantProductFeed/merchant/prod/cat/awCat') as $awCat) {
echo $awCat, PHP_EOL;
}
Live Demo
Note that fetching all $awCat elements from the source XML is rather pointless though, because all of them have "Bodycare & Fitness" for value. Of course you can also mix XPath and the implict API and just fetch the prod elements and then drill down to the various children of them.
Using XPath should be somewhat faster than iterating over the SimpleXmlElement object graph. Though it should be noted that the difference is in an neglectable area (read 0.000x vs 0.000y) for your feed. Still, if you plan to do more XML work, it pays off to familiarize yourself with XPath, because it's quite powerful. Think of it as SQL for XML.
For additional examples see
A simple program to CRUD node and node values of xml file and
PHP Manual - SimpleXml Basic Examples
Try this...
$url = "http://datafeed.api.productserve.com/datafeed/download/apikey/58bc4442611e03a13eca07d83607f851/cid/97,98,142,144,146,129,595,539,147,149,613,626,135,163,168,159,169,161,167,170,137,171,548,174,183,178,179,175,172,623,139,614,189,194,141,205,198,206,203,208,199,204,201,61,62,72,73,71,74,75,76,77,78,79,63,80,82,64,83,84,85,65,86,87,88,90,89,91,67,92,94,33,54,53,57,58,52,603,60,56,66,128,130,133,212,207,209,210,211,68,69,213,216,217,218,219,220,221,223,70,224,225,226,227,228,229,4,5,10,11,537,13,19,15,14,18,6,551,20,21,22,23,24,25,26,7,30,29,32,619,34,8,35,618,40,38,42,43,9,45,46,651,47,49,50,634,230,231,538,235,550,240,239,241,556,245,244,242,521,576,575,577,579,281,283,554,285,555,303,304,286,282,287,288,173,193,637,639,640,642,643,644,641,650,177,379,648,181,645,384,387,646,598,611,391,393,647,395,631,602,570,600,405,187,411,412,413,414,415,416,649,418,419,420,99,100,101,107,110,111,113,114,115,116,118,121,122,127,581,624,123,594,125,421,604,599,422,530,434,532,428,474,475,476,477,423,608,437,438,440,441,442,444,446,447,607,424,451,448,453,449,452,450,425,455,457,459,460,456,458,426,616,463,464,465,466,467,427,625,597,473,469,617,470,429,430,615,483,484,485,487,488,529,596,431,432,489,490,361,633,362,366,367,368,371,369,363,372,373,374,377,375,536,535,364,378,380,381,365,383,385,386,390,392,394,396,397,399,402,404,406,407,540,542,544,546,547,246,558,247,252,559,255,248,256,265,259,632,260,261,262,557,249,266,267,268,269,612,251,277,250,272,270,271,273,561,560,347,348,354,350,352,349,355,356,357,358,359,360,586,590,592,588,591,589,328,629,330,338,493,635,495,507,563,564,567,569,568/mid/2891/columns/merchant_id,merchant_name,aw_product_id,merchant_product_id,product_name,description,category_id,category_name,merchant_category,aw_deep_link,aw_image_url,search_price,delivery_cost,merchant_deep_link,merchant_image_url/format/xml/compression/gzip/";
$zd = gzopen($url, "r");
$data = gzread($zd, 1000000);
gzclose($zd);
if ($data !== false) {
$xml = simplexml_load_string($data);
foreach ($xml->merchant->prod as $pr) {
echo $pr->cat->awCat . "<br>";
}
}
<?php
$xmlstr = file_get_contents("compress.zlib://$url");
$xml = simplexml_load_string($xmlstr);
// you can transverse the xml tree however you want
foreach ($xml->merchant->prod as $line) {
// $line->cat->awCat -> you can use this
}
more information here
Use print_r($xml) to see the structure of the parsed XML feed.
Then it becomes obvious how you would traverse it:
foreach ($xml->merchant->prod as $prod) {
print $prod->pId;
print $prod->text->name;
print $prod->cat->awCat; # <-- which is what you wanted
print $prod->price->buynow;
}
$url = 'you url here';
$f = gzopen ($url, 'r');
$xml = new SimpleXMLElement (fread ($f, 1000000));
foreach($xml->xpath ('//prod') as $name)
{
echo (string) $name->cat->awCatId, "\r\n";
}

Categories