Some favorite site feeds aggregated locally: iPhone Development RSS   Adobe Labs RSS   Macrumors RSS

Monday, February 9, 2009

Navigating Yahoo! weather nodes

Monday, February 9, 2009    1 Comments

I took a straight XML approach to loading weather data from Yahoo! by simply using a URLLoader and using the address http://weather.yahooapis.com/forecastrss?p=01701. It returns an XML blob full of current and forecast data, which is great & it's very fast. Previously I was using a different service and it worked well for the 10% of the uptime the service provided (ugh). So a service on stronger footing was required, hence Yahoo!

Accessing the nodes by hand isn't exactly straight-forward though. One of the nodes I am most interested in looks like this in the resulting XML: <yweather:condition text="Mostly Cloudy" code="26" temp="57" ></yweather:condition> - perfectly understandable. But if you try to access it like so:
private function loadedXML(e:Event):void
{
var myXML:XML = new XML(e.target.data);
trace(myXML.channel.item.yweather:condition);
}
you'll get a compiler barf about that ":" in the node name. So you CAN access it like so:
private function loadedXML(e:Event):void
{
var myXML:XML = new XML(e.target.data);
trace(myXML.channel.item.children()[5]);
}
However that leaves an incredibly bad taste in my mouth as if the order of the tags ever change, this code breaks. I did throw a question to the FlashCoders list about this too. There has got to be a superior solution to this. I did quickly try to use the Yahoo! webapis classes to get this job done, but I was getting strange WeatherResultEvent errors and decided to quickly roll my own up.

UPDATE:

Thanks to FC, I looked to Namespaces. It took a bit to get it going, but here we are:
private function loadedXML(e:Event):void
{
var myXML:XML = new XML(e.target.data);
var foo:Namespace = new Namespace("http://xml.weather.yahoo.com/ns/rss/1.0");
trace( myXML.foo::condition.@text );
}
A major part of the problem was the online specifications from Yahoo! were wrong, and the namespace URI was incorrect. That didn't help much. Once I dug into the returned XML myself, I saw the problem right away.

UPDATE 2:

Here is something I wasn't aware that I could do. Now, there are several yweather:forecast nodes, one node per day reported. Well, you could grab the node attribute, which runs all the node values for each into one big, useless string that you can't substring because you don't know the length of each individual one, or you can do this:
var txt:String = myXML.channel.item.foo::forecast.@text[0];
var txt2:String = myXML.channel.item.foo::forecast.@text[1];
Works like a charm and you don't need to approach any hacks getting that data out of there. I tried it on a whim & it worked, albeit I am not completely up to snuff with XML as I was with AS2. AS3 is SO much better as I find out nearly daily. I don't think they need AS4 ever... just add some things to 3.

Labels: , ,