I'm experimenting with the Yahoo Weather API for a potential project I may work on. Considering that there may be other Weather API's used, it makes more sense from an architectural design standpoint to tranform Yahoo's data into my own XML data structure. This ensures that if the client decides that he/she likes Google's Weather API, or the Fox News API, all we need to do is create a new XSLT stylesheet to convert the data into the format recognized by our server.
Here is part of the Yahoo Weather Data, taken from here.:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<title>Yahoo! Weather - Portland, OR</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/97206_f.html</link>
<description>Yahoo! Weather for Portland, OR</description>
<language>en-us</language>
<lastBuildDate>Sat, 28 Jun 2008 4:53 pm PDT</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Portland" region="OR" country="US"/>
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="101" direction="300" speed="10" />
<yweather:atmosphere humidity="22" visibility="10" pressure="29.82" rising="2" />
<yweather:astronomy sunrise="5:24 am" sunset="9:03 pm"/>
<image>
<title>Yahoo! Weather</title>
<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com</link>
<url>http://l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url>
</image>
<item>
<title>Conditions for Portland, OR at 4:53 pm PDT</title>
<geo:lat>45.52</geo:lat>
<geo:long>-122.68</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/97206_f.html</link>
<pubDate>Sat, 28 Jun 2008 4:53 pm PDT</pubDate>
<yweather:condition text="Fair" code="34" temp="101" date="Sat, 28 Jun 2008 4:53 pm PDT" />
<description><![CDATA[
<img src="http://l.yimg.com/us.yimg.com/i/us/we/52/34.gif"/><br />
<b>Current Conditions:</b><br />
Fair, 101 F<BR />
<BR /><b>Forecast:</b><BR />
Sat - Mostly Clear. High: 97 Low: 65<br />
Sun - Mostly Sunny. High: 91 Low: 66<br />
<br />
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/USOR0275_f.html">Full Forecast at Yahoo! Weather</a><BR/>
(provided by The Weather Channel)<br/>
]]></description>
<yweather:forecast day="Sat" date="28 Jun 2008" low="65" high="97" text="Mostly Clear" code="33" />
<yweather:forecast day="Sun" date="29 Jun 2008" low="66" high="91" text="Mostly Sunny" code="34" />
<guid isPermaLink="false">97206_2008_06_28_16_53_PDT</guid>
</item>
</channel>
</rss><!-- api1.weather.sp1.yahoo.com compressed/chunked Sat Jun 28 17:19:32 PDT 2008 -->
Note that the temperature and other weather data is stored within elements that are part of the yweather namespace. The XSLT stylesheet below demonstrates how to obtain the temp attribute from the yweather:condition element:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0">
<xsl:template match="/">
<html>
<body>
<h2>Weather</h2>
<table border="1">
<xsl:for-each select="rss/channel">
<tr>
<td>title</td>
<td class="title"><xsl:value-of select="title" /></td>
</tr>
<tr>
<td>link</td>
<td class="link"><xsl:value-of select="link" /></td>
</tr>
<tr>
<td>curCond</td>
<td class="curCond">
<xsl:value-of select="//yweather:condition/@text" />
</td>
</tr>
<tr>
<td>curTemp</td>
<td class="curTemp">
<xsl:value-of select="//yweather:condition/@temp" />
</td>
<td id="curTemp">
<xsl:value-of select="//yweather:condition/@temp" />
</td>
</tr>
<xsl:for-each select="//yweather:forecast">
<tr>
<td>forecast</td><td class="day">day: <xsl:value-of select="@day" /></td>
</tr>
<tr>
<td></td><td class="date">date: <xsl:value-of select="@date" /></td>
</tr>
<tr>
<td></td><td class="low">low: <xsl:value-of select="@low" /></td>
</tr>
<tr>
<td></td><td class="high">high: <xsl:value-of select="@high" /></td>
On another note, I've done XML conversions before the hard way: By parsing the XML with PHP or JSP and dynamically rebuilding the XML! While this would also work to solve my problem, using XSLT will allow me to keep the transformation layer separate from the business logic.
Although this was somewhat time consuming getting started with XSLT and converting XML with namespaces, I can already feel the weight being lifted off my mind knowing that changing my data sources won't involve troubleshooting PHP errors!
2 comments:
I realize this post is 5 years old now, but it really helped me. I was actually working on the same application of parsing Yahoo's weather XML and kept getting hung up on the namespace.
Thanks for this.
This is really an excellent blog as well as its content.
Social Media Marketing
Post a Comment