I have a php file setup to pull through ONE XML data feed, What I would like to do is load up to 4 feeds into it and if possible make it select a random item too. Then parse that into an jQuery News Ticker.
My current PHP is as follows...
<?php
$feed = new DOMDocument();
$feed->load('/feed');
$json = array();
$json['title'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
$json['description'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
$json['link'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('link')->item(0)->firstChild->nodeValue;
$items = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('item');
$json['item'] = array();
$i = 0;
foreach($items as $item) {
$title = $item->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
$description = $item->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
$pubDate = $item->getElementsByTagName('pubDate')->item(0)->firstChild->nodeValue;
$guid = $item->getElementsByTagName('guid')->item(0)->firstChild->nodeValue;
$json['item'][$i++]['title'] = $title;
$json['item'][$i++]['description'] = $description;
$json['item'][$i++]['pubdate'] = $pubDate;
$json['item'][$i++]['guid'] = $guid;
echo '<li class="news-item">'.$title.'</li>';
}
//echo json_encode($json);
?>
How can I modify this to load more than one feed into the file?
Thanks in advance
The simplest approach to doing this is wrapping another loop around the code you have. It's not the cleanest way but will probably suffice for the purpose.
In general, IMO, it's always beneficial to learn the basics of the language first. E.g. PHP manual on foreach
This is roughly what the loop needs to look like:
$my_feeds = array("http://.....", "http://.....", "http://.....");
foreach ($my_feeds as $my_feed)
{
// This is where your code starts
$feed = new DOMDocument();
$feed->load($my_feed); <--------------- notice the variable
$json = array();
... and the rest of the code
}
this will walk through all the URLs in $my_feeds, open the RSS source, fetch all the items from it, and output them.
If I'm reading your question right, what you may want to do is turn your code into a function, which you would then run inside a foreach loop for each url (which you could store in an array or other data structure).
Edit: If you don't know much about functions, this tutorial section might help you. http://devzone.zend.com/9/php-101-part-6-functionally-yours/
Related
First, I am pretty clueless with PHP, so be kind! I am working on a site for an SPCA (I'm a Vet and a part time geek). The PHP accesses an xml file from a portal used to administer the shelter and store images, info. The file writes that xml data to JSON and then I use the JSON data in a handlebars template, etc. I am having a problem getting some data from the xml file to outprint to JSON.
The xml file is like this:
</DataFeedAnimal>
<AdditionalPhotoUrls>
<string>doc_73737.jpg</string>
<string>doc_74483.jpg</string>
<string>doc_74484.jpg</string>
</AdditionalPhotoUrls>
<PrimaryPhotoUrl>19427.jpg</PrimaryPhotoUrl>
<Sex>Male</Sex>
<Type>Cat</Type>
<YouTubeVideoUrls>
<string>http://www.youtube.com/watch?v=6EMT2s4n6Xc</string>
</YouTubeVideoUrls>
</DataFeedAnimal>
In the PHP file, written by a friend, the code is below, (just part of it), to access that XML data and write it to JSON:
<?php
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/AnimalsForAdoption.aspx";
if ($_GET["type"] == "found") {
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/foundanimals.aspx";
} else if ($_GET["type"] == "lost") {
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/lostanimals.aspx";
}
$response_xml_data = file_get_contents($url);
$xml = simplexml_load_string($response_xml_data);
$data = array();
foreach($xml->DataFeedAnimal as $animal)
{
$item = array();
$item['sex'] = (string)$animal->Sex;
$item['photo'] = (string)$animal->PrimaryPhotoUrl;
$item['videos'][] = (string)$animal->YouTubeVideoUrls;
$item['photos'][] = (string)$animal->PrimaryPhotoUrl;
foreach($animal->AdditionalPhotoUrls->string as $photo) {
$item['photos'][] = (string)$photo;
}
$item['videos'] = array();
$data[] = $item;
}
echo file_put_contents('../adopt.json', json_encode($data));
echo json_encode($data);
?>
The JSON output works well but I am unable to get 'videos' to write out to the JSON file as the 'photos' do. I just get '/n'!
Since the friend who helped with this is no longer around, I am stuck. I have tried similar code to the foreach statement for photos but am getting nowhere. Any help would be appreciated and the pets would appreciate it as well!
The trick with such implementations is to always look what you have got by dumping data structures to a log file or command line. Then to take a look at the documentation of the data you see. That way you know exactly what data you are working with and how to work with it ;-)
Here it turns out that the video URLs you are interested in are placed inside an object of type SimpleXMLElement with public properties, which is not really surprising if you look at the xml structure. The documentation of class SimpleXMLElement shows the method children() which iterates through all children. Just what we are looking for...
That means a clean implementation to access those sets should go along these lines:
foreach($animal->AdditionalPhotoUrls->children() as $photo) {
$item['photos'][] = (string)$photo;
}
foreach($animal->YouTubeVideoUrls->children() as $video) {
$item['videos'][] = (string)$video;
}
Take a look at this full and working example:
<?php
$response_xml_data = <<< EOT
<DataFeedAnimal>
<AdditionalPhotoUrls>
<string>doc_73737.jpg</string>
<string>doc_74483.jpg</string>
<string>doc_74484.jpg</string>
</AdditionalPhotoUrls>
<PrimaryPhotoUrl>19427.jpg</PrimaryPhotoUrl>
<Sex>Male</Sex>
<Type>Cat</Type>
<YouTubeVideoUrls>
<string>http://www.youtube.com/watch?v=6EMT2s4n6Xc</string>
<string>http://www.youtube.com/watch?v=hgfg83mKFnd</string>
</YouTubeVideoUrls>
</DataFeedAnimal>
EOT;
$animal = simplexml_load_string($response_xml_data);
$item = [];
$item['sex'] = (string)$animal->Sex;
$item['photo'] = (string)$animal->PrimaryPhotoUrl;
$item['photos'][] = (string)$animal->PrimaryPhotoUrl;
foreach($animal->AdditionalPhotoUrls->children() as $photo) {
$item['photos'][] = (string)$photo;
}
$item['videos'] = [];
foreach($animal->YouTubeVideoUrls->children() as $video) {
$item['videos'][] = (string)$video;
}
echo json_encode($item);
The obvious output of this is:
{
"sex":"Male",
"photo":"19427.jpg",
"photos" ["19427.jpg","doc_73737.jpg","doc_74483.jpg","doc_74484.jpg"],
"videos":["http:\/\/www.youtube.com\/watch?v=6EMT2s4n6Xc","http:\/\/www.youtube.com\/watch?v=hgfg83mKFnd"]
}
I would however like to add a short hint:
In m eyes it is questionable to convert such structured information into an associative array. Why? Why not a simple json_encode($animal)? The structure is perfectly fine and should be easy to work with! The output of that would be:
{
"AdditionalPhotoUrls":{
"string":[
"doc_73737.jpg",
"doc_74483.jpg",
"doc_74484.jpg"
]
},
"PrimaryPhotoUrl":"19427.jpg",
"Sex":"Male",
"Type":"Cat",
"YouTubeVideoUrls":{
"string":[
"http:\/\/www.youtube.com\/watch?v=6EMT2s4n6Xc",
"http:\/\/www.youtube.com\/watch?v=hgfg83mKFnd"
]
}
}
That structure describes objects (items with an inner structure, enclosed in json by {...}), not just arbitrary arrays (sets without a structure, enclosed in json by a [...]). Arrays are only used for the two unstructured sets of strings in there: photos and videos. This is much more logical, once you think about it...
Assuming the XML Data and the JSON data are intended to have the same structure. I would take a look at this: PHP convert XML to JSON
You may not need for loops at all.
I'm trying to parse RSS feeds from some medias. My script works for most of them. The problem is that I need to agregate all of them, eventhough they are malformed.
I don't manage to get the description of these two feeds. How could I proceed anyway ?
Here is my script :
<?php
function RSS_items ($url) {
$i = 0;
$doc = new DOMDocument();
$doc->load($url);
$channels = $doc->getElementsByTagName('channel');
foreach($channels as $channel) {
$items = $channel->getElementsByTagName('item');
foreach($items as $item) {
$i++;
$y[$i]['title'] = $item->getElementsByTagName('title')->item(0)->firstChild->textContent;
$y[$i]['link'] = $item->getElementsByTagName('link')->item(0)->firstChild->textContent;
$y[$i]['updated'] = $item->getElementsByTagName('pubDate')->item(0)->firstChild->textContent;
$y[$i]['description'] = $item->getElementsByTagName('description')->item(0)->firstChild->textContent;
}
}
echo '<pre>';
print_r ($y);
echo '</pre>';
}
// the two malformed feeds
RSS_items ('http://www.lefigaro.fr/rss/figaro_actualites-a-la-une.xml');
RSS_items ('https://francais.rt.com/rss');
?>
Problem of your code is in useing firstChild property that select first child of element. But in target XML, description tag hasn't any childs that you want to select first of them. Remove it from code. The result should be like this
$item->getElementsByTagName('description')->item(0)->textContent;
I am using PHP HTML DOM Parser to get data from another site. First i get URLs of my trades on this site and than i send another request on each trade url to get comments .I want to make an array of comments so i can sort them later. Why i cant create array ?
It looks like this
include_once('simple_html_dom.php');
$result = array();
$html = file_get_html('http://csgolounge.com/profile?id='.$steamid);
foreach($html->find('div.tradepoll') as $trade)
{
$tradeid = $trade->find('.tradeheader')[0]->find('a')[0]->href;
$html = file_get_html('http://csgolounge.com/'.$tradeid);
foreach($html->find('div.message') as $message)
{
if($message->find('p',0)){}
else
{
$left = $message->find('.msgleft')[0];
$right = $message->find('.msgright')[0];
//information about comments
$time = trim(strip_tags_content($left->innertext));
$text = $left->find('.msgtxt')[0];
$result[$time]['time'] = $time;
$result[$time]['text'] = $text;
}
}
}
echo json_encode($result);
If i echo $time or $text i always get data successfully.
I found what was the problem.
The Simple HTML DOM Parser does not clean up memory in the DOM each time file_get_html or str_get_html is called so it needs to be done explicity each time you have finished with the current DOM.
So I added $html->clear(); at the end of the loop.
Credits: electrictoolbox.com
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);
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I'm currently using Magpie RSS but it sometimes falls over when the RSS or Atom feed isn't well formed. Are there any other options for parsing RSS and Atom feeds with PHP?
I've always used the SimpleXML functions built in to PHP to parse XML documents. It's one of the few generic parsers out there that has an intuitive structure to it, which makes it extremely easy to build a meaningful class for something specific like an RSS feed. Additionally, it will detect XML warnings and errors, and upon finding any you could simply run the source through something like HTML Tidy (as ceejayoz mentioned) to clean it up and attempt it again.
Consider this very rough, simple class using SimpleXML:
class BlogPost
{
var $date;
var $ts;
var $link;
var $title;
var $text;
}
class BlogFeed
{
var $posts = array();
function __construct($file_or_url)
{
$file_or_url = $this->resolveFile($file_or_url);
if (!($x = simplexml_load_file($file_or_url)))
return;
foreach ($x->channel->item as $item)
{
$post = new BlogPost();
$post->date = (string) $item->pubDate;
$post->ts = strtotime($item->pubDate);
$post->link = (string) $item->link;
$post->title = (string) $item->title;
$post->text = (string) $item->description;
// Create summary as a shortened body and remove images,
// extraneous line breaks, etc.
$post->summary = $this->summarizeText($post->text);
$this->posts[] = $post;
}
}
private function resolveFile($file_or_url) {
if (!preg_match('|^https?:|', $file_or_url))
$feed_uri = $_SERVER['DOCUMENT_ROOT'] .'/shared/xml/'. $file_or_url;
else
$feed_uri = $file_or_url;
return $feed_uri;
}
private function summarizeText($summary) {
$summary = strip_tags($summary);
// Truncate summary line to 100 characters
$max_len = 100;
if (strlen($summary) > $max_len)
$summary = substr($summary, 0, $max_len) . '...';
return $summary;
}
}
With 4 lines, I import a rss to an array.
$feed = implode(file('http://yourdomains.com/feed.rss'));
$xml = simplexml_load_string($feed);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
For a more complex solution
$feed = new DOMDocument();
$feed->load('file.rss');
$json = array();
$json['title'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
$json['description'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
$json['link'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('link')->item(0)->firstChild->nodeValue;
$items = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('item');
$json['item'] = array();
$i = 0;
foreach($items as $key => $item) {
$title = $item->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
$description = $item->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
$pubDate = $item->getElementsByTagName('pubDate')->item(0)->firstChild->nodeValue;
$guid = $item->getElementsByTagName('guid')->item(0)->firstChild->nodeValue;
$json['item'][$key]['title'] = $title;
$json['item'][$key]['description'] = $description;
$json['item'][$key]['pubdate'] = $pubDate;
$json['item'][$key]['guid'] = $guid;
}
echo json_encode($json);
Your other options include:
SimplePie
Last RSS
PHP Universal Feed Parser
I would like introduce simple script to parse RSS:
$i = 0; // counter
$url = "http://www.banki.ru/xml/news.rss"; // url to parse
$rss = simplexml_load_file($url); // XML parser
// RSS items loop
print '<h2><img style="vertical-align: middle;" src="'.$rss->channel->image->url.'" /> '.$rss->channel->title.'</h2>'; // channel title + img with src
foreach($rss->channel->item as $item) {
if ($i < 10) { // parse only 10 items
print ''.$item->title.'<br />';
}
$i++;
}
If feed isn't well-formed XML, you're supposed to reject it, no exceptions. You're entitled to call feed creator a bozo.
Otherwise you're paving way to mess that HTML ended up in.
The HTML Tidy library is able to fix some malformed XML files. Running your feeds through that before passing them on to the parser may help.
I use SimplePie to parse a Google Reader feed and it works pretty well and has a decent feature set.
Of course, I haven't tested it with non-well-formed RSS / Atom feeds so I don't know how it copes with those, I'm assuming Google's are fairly standards compliant! :)
Personally I use BNC Advanced Feed Parser- i like the template system that is very easy to use
The PHP RSS reader - http://www.scriptol.com/rss/rss-reader.php - is a complete but simple parser used by thousand of users...
Another great free parser - http://bncscripts.com/free-php-rss-parser/
It's very light ( only 3kb ) and simple to use!