RSS feeds and other syndication formats are becoming common and using an aggregator like NetNewsWire, Sharpreader or Bloglines is an easy way to keep up-to-date with your favourite websites without having to visit all of them every day. But what if you want that RSS content on your own website? Here’s a very simple way to reuse RSS weather information from www.rssweather.com with PHP.
I’ll use an example that reads the weather for West Wales and San Francisco because I live in West Wales and I’m visiting California soon. This is a very quick-and-dirty solution that doesn’t make much of the fact that RSS is an XML format; all I want is the temperature and the cloud cover on my website every day.
The feeds from rssweather.com are simple enough to understand - there are a number of <item> nodes in the XML and the first <item> is always the Current Weather and it contains a <content:encoded> node that has the info I want. I can make use of the fact that the content is very highly structured and consistent to extract what I want without having to parse the RSS XML.
RSS is a generalised syndication format. If you wanted to broadcast weather information as XML from scratch you probably wouldn’t want to use RSS because all the interesting data, made of discrete and well-defined items, is collected in the pre-formatted undifferentiated lump of the <content:encoded> node; but RSS has the benefit that it can be consumed by lots of existing applications and that’s why rssweather.com uses RSS. I’ll have to parse the pre-formatted information to extract the few data items in which I’m interested.
Part of the value of the <content:encoded> node always looks like this:
<span class=”sky”>Mostly clear</span> <span class=”temp”>54°F</span>
and it’ll be easy pick this up with a regular expression.
Get the RSS - once
First of all, you need to consume the RSS. Understandably, rssweather.com don’t want you hammering their server so if you’re testing your own application, test with a copy on your own server until you’re happy everything works.
A good way to pick up the RSS feed with PHP is to use the fopen function which can open remote URLs as well as local files. This code opens a file handle, reads the contents into a buffer and closes the file:
$url = “http://http://www.rssweather.com/rss.php?etc
if (!($fp = fopen($url, “r”))) {
die(”could not open RSS source”);
}
$data = fread($fp,8912);
fclose($fp);
We could go straight ahead and extract the two values we want using the PHP function preg_match_all — but instead I’ll show you a simple way of parsing the XML source.
Parsing the RSS / XML
xml_parse_into_struct parses the XML content into two array structures and it’s a bit easier to handle than SAX event-driven processing; it’s a good solution if your XML source isn’t too massive.
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
Next, we find the <content:encoded> node by iterating through the $vals array. Then we can read the value from the [’value’] element:
foreach ($vals as $xml_elem) {
if($xml_elem[’tag’] == ‘CONTENT:ENCODED’){
$weather = $xml_elem[’value’];
break;
}
}
Regexp to get the data
Now we have the content we can use a regular expression to pick out the values we want.
$itemregexp = “%<span class=”sky”>(.+?)< /span>(.+?) >(.+?)< /span> %is”;
$match_count = preg_match_all($itemregexp, $weather, $items);
if($match_count > 0){
$sky = $items[1][0];
$temp = $items[3][0];
}
Save it for later inclusion
We don’t want to hammer rssweather.com’s server so we’ll save this information as a file that we can include into a PHP page. When that’s working ok we can setup a cron job to do it for us once a day.
Write an include file :
$inc = “<dl>”;
$inc .= “<dt>Sky</dt>”;
$inc .= “<dt>Temp</dt>”;
$inc .= “<dd>”.$sky.”</dd>”;
$inc .= “<dd>”.temp.”</dd>”;
$inc .= “</dl>”;
$filename = {myfilename}
$handle= fopen($filename,’w’);
fwrite($handle, $inc);
fclose($handle);








One Comment
Thanks David, this really Thanks David, this really helped me out. I was doing something similar using simplexml_load_string(), but this broke on me when I upgraded to PHP5.1.2. Struggling to fix that I stumbled upon your solution. I do a bit different parsing, but this allowed me to quickly extract the data from the feed. You can see mine in action here: http://www.polarlava.com/hawaii/