Web Service学习笔记:利用YAHOO公开API做天气预报Web服务
难道是因为在这个地方,我放了个本人在我的小站的链接地址,就违反了首页的规则,这绝对的原创,我星星苦苦写的,虽说没有很高的技术含量,但也是有点的,在放一次,如果被撤下来,希望能给我个合理的解释。在此,谢谢园子里了的管理人员。
学了一段时间的Web服务,今天做了一个Web服务,利用YAHOO的公开天气API做自己的Web服务,主要是想练练手。现在把过程和心得分享给大家。
文章在我小站的地址:Web Service学习笔记:利用YAHOO公开API做天气预报Web服务
求教:这个Web服务还有个不完善的地方,Web服务的CityNameToCityNum方法,这个最重要,他是把省会和直辖市的名字转换为编号,因为YAHOO传的参数不是城市名字的区号,全是自己的,而我又想不到更好的获得YAHOO城市对应的编号的方法,所以就创建了HASHTABLE存储了中国的各个省会城市和直辖市,希望有高手提出更好的方法,能不用这样,直接找YAHOO获取编号,提取更多的城市,而不用把所有的中国所有的城市全写在HASHTABLE里。
Web服务地址:http://www.h2bbs.com/Weather/Weather.asmx
原理:
在Yahoo的Developer Network
http://developer.yahoo.com/weather/
详细地介绍了Yahoo天气预报的API调用方法,这里用C#来实现,本文主要是利用它的API做Web服务,其它的应用由网友们自由发挥
首先了解Yahoo Weather Api的RSS Response格式(这是下午我查我家银川天气时返回的RSS):
<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 - Yinchuan, CH</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Yinchuan__CH/*[url]http://weather.yahoo.com/forecast/CHXX0259_f.html[/url]</link>
<description>Yahoo! Weather for Yinchuan, CH</description>
<language>en-us</language>
<lastBuildDate>Tue, 14 Oct 2008 11:00 am CST</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Yinchuan" region="" country="CH"/>
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="56" direction="360" speed="4" />
<yweather:atmosphere humidity="56" visibility="999" pressure="" rising="0" />
<yweather:astronomy sunrise="7:03 am" sunset="6:19 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 Yinchuan, CH at 11:00 am CST</title>
<geo:lat>38.48</geo:lat>
<geo:long>106.22</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Yinchuan__CH/*[url]http://weather.yahoo.com/forecast/CHXX0259_f.html[/url]</link>
<pubDate>Tue, 14 Oct 2008 11:00 am CST</pubDate>
<yweather:condition text="Mostly Cloudy" code="28" temp="56" date="Tue, 14 Oct 2008 11:00 am CST" />
<description>
<![CDATA[
<img src="
[img]http://l.yimg.com/us.yimg.com/i/us/we/52/28.gif[/img]"/><br />
<b>Current Conditions:</b><br />
Mostly Cloudy, 56 F<BR />
<BR /><b>Forecast:</b><BR />
Tue - Mostly Cloudy. High: 68 Low: 47<br />
Wed - Partly Cloudy. High: 70 Low: 44<br />
<br />
<a href="Full'>http://us.rd.yahoo.com/dailynews/rss/weather/Yinchuan__CH/*http://weather.yahoo.com/forecast/CHXX0259_f.html">Full Forecast at Yahoo! Weather</a><BR/>
(provided by The Weather Channel)<br/>
]]>
</description>
<yweather:forecast day="Tue" date="14 Oct 2008" low="47" high="68" text="Mostly Cloudy" code="28" />
<yweather:forecast day="Wed" date="15 Oct 2008" low="44" high="70" text="Partly Cloudy" code="30" />
<guid isPermaLink="false">CHXX0259_2008_10_14_11_00_CST</guid>
</item>
</channel>
</rss>
<!-- api5.weather.sp1.yahoo.com compressed/chunked Mon Oct 13 22:30:39 PDT 2008 -->
其中最重要的是后面的几行,查询当天和第二天的天气情况,我们要获取的天气信息就在里面,代码如下:
<yweather:forecast day="Wed" date="15 Oct 2008" low="44" high="70" text="Partly Cloudy" code="30" />
我们所需要用到的Node是/rss/channel/item/yweather: forecast;这个节点里的东西是我们需要的。
知道了这些,我们接下来要做的就是在VS中建立WEB服务,并添加下面的代码:
{
/// <summary>
/// Weather 的摘要说明
/// </summary>
[WebService(Name = "WeatherWebService", Namespace = "http://www.h2bbs.com/Weather/Weather.asmx", Description = "利用YAHOO公开的API接口,在Web服务实现公开的天气预报调用服务。")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class Weather : System.Web.Services.WebService
{
[WebMethod(Description = "根据城市的名称返回该城市的天气预报情况,只能查询省会和直辖市的天气情况。")]
public DataSet GetWeather(string strCityName)
{
string strXml = "http://xml.weather.yahoo.com/forecastrss?p=CHXX" + CityNameToCityNum(strCityName);
XmlDocument Weather = new XmlDocument();
Weather.Load(strXml);
XmlNamespaceManager namespacemanager = new XmlNamespaceManager(Weather.NameTable);
namespacemanager.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0");
XmlNodeList nodes = Weather.SelectNodes("/rss/channel/item/yweather:forecast", namespacemanager);
//XmlNodeList nodes = Weather.GetElementsByTagName("forecast", "http://xml.weather.yahoo.com/ns/rss/1.0");
DataSet dstWeather = new DataSet();
DataTable dtblWeather = new DataTable("Weather");
dstWeather.Tables.Add(dtblWeather);
dstWeather.Tables["Weather"].Columns.Add("Date", typeof(string));
dstWeather.Tables["Weather"].Columns.Add("Week", typeof(string));
dstWeather.Tables["Weather"].Columns.Add("Weather", typeof(string));
dstWeather.Tables["Weather"].Columns.Add("Tlow", typeof(string));
dstWeather.Tables["Weather"].Columns.Add("Thigh", typeof(string));
if (nodes.Count > 0)
{
foreach (XmlNode node in nodes)
{
DataRow drowWeather = dstWeather.Tables["Weather"].NewRow();
drowWeather["Date"] = EmonthToCmonth(node.SelectSingleNode("@date").Value.ToString());
drowWeather["Week"] = EweekToCweek(node.SelectSingleNode("@day").Value.ToString()) + "(" + node.SelectSingleNode("@day").Value.ToString() + ")";
drowWeather["Weather"] = node.SelectSingleNode("@text").Value;
drowWeather["Tlow"] = FToC(int.Parse(node.SelectSingleNode("@low").Value)) + "℃";
drowWeather["Thigh"] = FToC(int.Parse(node.SelectSingleNode("@high").Value)) + "℃";
dstWeather.Tables["Weather"].Rows.Add(drowWeather);
}
return dstWeather;
}
else
{
DataRow drowNone = dstWeather.Tables["Weather"].NewRow();
drowNone["Date"] = "None";
drowNone["Week"] = "None";
drowNone["Weather"] = "None";
drowNone["Tlow"] = "None";
drowNone["Thigh"] = "None";
dstWeather.Tables["Weather"].Rows.Add(drowNone);
return dstWeather;
}
}
/// <summary>
/// 从华氏转换成摄氏
/// </summary>
/// <param name="f">华氏度</param>
/// <returns></returns>
private string FToC(int f)
{
return Math.Round((f - 32) / 1.8, 1).ToString();
}
/// <summary>
/// 从星期英文缩写转汉字
/// </summary>
/// <param name="strEweek">星期的英文缩写</param>
/// <returns></returns>
private string EweekToCweek(string strEweek)
{
switch (strEweek)
{
case "Mon":
return "星期一";
break;
case "Tue":
return "星期二";
break;
case "Wed":
return "星期三";
break;
case "Thu":
return "星期四";
break;
case "Fri":
return "星期五";
break;
case "Sat":
return "星期六";
break;
case "Sun":
return "星期日";
break;
default:
return "传参错误";
break;
}
}
/// <summary>
/// 从月英文缩写转汉字
/// </summary>
/// <param name="strReplace">需要替换的年月日</param>
/// <returns></returns>
private string EmonthToCmonth(string strReplace)
{
return Convert.ToDateTime(strReplace).ToString("yyyy年MM月dd日");
}
/// <summary>
/// 根据城市名称返回城市编号
/// </summary>
/// <param name="strCityName">城市名称</param>
/// <returns></returns>
private string CityNameToCityNum(string strCityNameToNum)
{
//中国各个省会和直辖市对应的查询代码
Hashtable htWeather = new Hashtable();
htWeather.Add("北京", "0008");
htWeather.Add("天津", "0133");
htWeather.Add("杭州", "0044");
htWeather.Add("合肥", "0448");
htWeather.Add("上海", "0116");
htWeather.Add("福州", "0031");
htWeather.Add("重庆", "0017");
htWeather.Add("南昌", "0097");
htWeather.Add("香港", "0049");
htWeather.Add("济南", "0064");
htWeather.Add("澳门", "0512");
htWeather.Add("郑州", "0165");
htWeather.Add("呼和浩特", "0249");
htWeather.Add("乌鲁木齐", "0135");
htWeather.Add("长沙", "0013");
htWeather.Add("银川", "0259");
htWeather.Add("广州", "0037");
htWeather.Add("拉萨", "0080");
htWeather.Add("海口", "0502");
htWeather.Add("南宁", "0100");
htWeather.Add("成都", "0016");
htWeather.Add("石家庄", "0122");
htWeather.Add("贵阳", "0039");
htWeather.Add("太原", "0129");
htWeather.Add("昆明", "0076");
htWeather.Add("沈阳", "0119");
htWeather.Add("西安", "0141");
htWeather.Add("长春", "0010");
htWeather.Add("兰州", "0079");
htWeather.Add("西宁", "0236");
htWeather.Add("南京", "0099");
object cityNum = htWeather[strCityNameToNum];
if (cityNum == null)
{
return "City not found";
}
else
{
return cityNum.ToString();
}
}
}
}
别忘了"using System.Xml;"哦!
Web服务的代码中有一个Web公开方法,四个私有方法:
(1)GetWeather方法是公共方法,提供Web调用。
(2)FToC方法,他主要是把RSS返回的华氏温度转换成摄氏温度,其实这一步可以不用的,当初没发现,URL中加点参数就返回的是摄氏温度。
(3)EweekToCweek方法,他主要是把英文的星期缩写变成中文。
(4)EmonthToCmonth方法,它主要是把英文的月份缩写变成中文,并重新排序。
(5)CityNameToCityNum方法,这个最重要,他是把省会和直辖市的名字转换为编号,因为YAHOO传的参数不是城市名字的区号,全是自己的,而我又想不到更好的获得YAHOO城市对应的编号的方法,所以就只能支持这么几个城市了,希望有高手提出更好的方法,能不用这样,直接找YAHOO获取编号。
查询个中国随便的省会,效果如下
- <DataSet xmlns="http://www.h2bbs.com/WebService/Weather.asmx">
- <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
- <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
- <xs:complexType>
- <xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="Weather">
- <xs:complexType>
- <xs:sequence>
<xs:element name="Date" type="xs:string" minOccurs="0" />
<xs:element name="Week" type="xs:string" minOccurs="0" />
<xs:element name="Weather" type="xs:string" minOccurs="0" />
<xs:element name="Tlow" type="xs:string" minOccurs="0" />
<xs:element name="Thigh" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
- <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
- <NewDataSet xmlns="">
- <Weather diffgr:id="Weather1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<Date>2008年10月14日</Date>
<Week>星期二(Tue)</Week>
<Weather>Clear</Weather>
<Tlow>16.1℃</Tlow>
<Thigh>26.7℃</Thigh>
</Weather>
- <Weather diffgr:id="Weather2" msdata:rowOrder="1" diffgr:hasChanges="inserted">
<Date>2008年10月15日</Date>
<Week>星期三(Wed)</Week>
<Weather>Sunny</Weather>
<Tlow>16.7℃</Tlow>
<Thigh>28.3℃</Thigh>
</Weather>
</NewDataSet>
</diffgr:diffgram>
</DataSet>
写完了!最后希望能给大家带来收获!
出处:http://VisualStudio.cnblogs.com/
个人网站:H2站长论坛
本文版权归作者和博客园还有H2站长论坛共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。