难道是因为在这个地方,我放了个本人在我的小站的链接地址,就违反了首页的规则,这绝对的原创,我星星苦苦写的,虽说没有很高的技术含量,但也是有点的,在放一次,如果被撤下来,希望能给我个合理的解释。在此,谢谢园子里了的管理人员。
学了一段时间的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]
< 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
< url > http: // l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif
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]
< 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]"/>
< 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 >
其中最重要的是后面的几行,查询当天和第二天的天气情况,我们要获取的天气信息就在里面,代码如下:
< 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服务,并添加下面的代码:
{
/**////
/// Weather 的摘要说明
///
[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;
}
}
/**////
/// 从华氏转换成摄氏
///
/// 华氏度
///
private string FToC(int f)
{
return Math.Round((f - 32) / 1.8, 1).ToString();
}
/**////
/// 从星期英文缩写转汉字
///
/// 星期的英文缩写
///
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;
}
}
/**////
/// 从月英文缩写转汉字
///
/// 需要替换的年月日
///
private string EmonthToCmonth(string strReplace)
{
return Convert.ToDateTime(strReplace).ToString("yyyy年MM月dd日");
}
/**////
/// 根据城市名称返回城市编号
///
/// 城市名称
///
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 >
写完了!最后希望能给大家带来收获!