难道是因为在这个地方,我放了个本人在我的小站的链接地址,就违反了首页的规则,这绝对的原创,我星星苦苦写的,虽说没有很高的技术含量,但也是有点的,在放一次,如果被撤下来,希望能给我个合理的解释。在此,谢谢园子里了的管理人员。
学了一段时间的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):
<?
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
-
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
=
"
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
"
/>
我们所需要用到的Node是/rss/channel/item/yweather: forecast;这个节点里的东西是我们需要的。
知道了这些,我们接下来要做的就是在VS中建立WEB服务,并添加下面的代码:
namespace
Weather
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <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
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
[WebMethod(Description = "根据城市的名称返回该城市的天气预报情况,只能查询省会和直辖市的天气情况。")]
public DataSet GetWeather(string strCityName)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string strXml = "http://xml.weather.yahoo.com/forecastrss?p=CHXX" + CityNameToCityNum(strCityName);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
XmlDocument Weather = new XmlDocument();
Weather.Load(strXml);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//XmlNodeList nodes = Weather.GetElementsByTagName("forecast", "http://xml.weather.yahoo.com/ns/rss/1.0");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DataSet dstWeather = new DataSet();
DataTable dtblWeather = new DataTable("Weather");
dstWeather.Tables.Add(dtblWeather);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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));
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (nodes.Count > 0)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach (XmlNode node in nodes)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataRow drowWeather = dstWeather.Tables["Weather"].NewRow();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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)) + "℃";
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dstWeather.Tables["Weather"].Rows.Add(drowWeather);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return dstWeather;
}
else
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataRow drowNone = dstWeather.Tables["Weather"].NewRow();
drowNone["Date"] = "None";
drowNone["Week"] = "None";
drowNone["Weather"] = "None";
drowNone["Tlow"] = "None";
drowNone["Thigh"] = "None";
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
dstWeather.Tables["Weather"].Rows.Add(drowNone);
return dstWeather;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 从华氏转换成摄氏
/// </summary>
/// <param name="f">华氏度</param>
/// <returns></returns>
private string FToC(int f)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return Math.Round((f - 32) / 1.8, 1).ToString();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 从星期英文缩写转汉字
/// </summary>
/// <param name="strEweek">星期的英文缩写</param>
/// <returns></returns>
private string EweekToCweek(string strEweek)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
switch (strEweek)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 从月英文缩写转汉字
/// </summary>
/// <param name="strReplace">需要替换的年月日</param>
/// <returns></returns>
private string EmonthToCmonth(string strReplace)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return Convert.ToDateTime(strReplace).ToString("yyyy年MM月dd日");
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 根据城市名称返回城市编号
/// </summary>
/// <param name="strCityName">城市名称</param>
/// <returns></returns>
private string CityNameToCityNum(string strCityNameToNum)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//中国各个省会和直辖市对应的查询代码
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");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
object cityNum = htWeather[strCityNameToNum];
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (cityNum == null)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return "City not found";
}
else
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return cityNum.ToString();
}
}
}
}
别忘了"using System.Xml;"哦!
Web服务的代码中有一个Web公开方法,四个私有方法:
(1)GetWeather方法是公共方法,提供Web调用。
(2)FToC方法,他主要是把RSS返回的华氏温度转换成摄氏温度,其实这一步可以不用的,当初没发现,URL中加点参数就返回的是摄氏温度。
(3)EweekToCweek方法,他主要是把英文的星期缩写变成中文。
(4)EmonthToCmonth方法,它主要是把英文的月份缩写变成中文,并重新排序。
(5)CityNameToCityNum方法,这个最重要,他是把省会和直辖市的名字转换为编号,因为YAHOO传的参数不是城市名字的区号,全是自己的,而我又想不到更好的获得YAHOO城市对应的编号的方法,所以就只能支持这么几个城市了,希望有高手提出更好的方法,能不用这样,直接找YAHOO获取编号。
![](https://www.cnblogs.com/images/cnblogs_com/visualstudio/13.jpg)
查询个中国随便的省会,效果如下
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
DataSet xmlns
=
"
http://www.h2bbs.com/WebService/Weather.asmx
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:schema id
=
"
NewDataSet
"
xmlns
=
""
xmlns:xs
=
"
http://www.w3.org/2001/XMLSchema
"
xmlns:msdata
=
"
urn:schemas-microsoft-com:xml-msdata
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:element name
=
"
NewDataSet
"
msdata:IsDataSet
=
"
true
"
msdata:UseCurrentLocale
=
"
true
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:complexType
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:choice minOccurs
=
"
0
"
maxOccurs
=
"
unbounded
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:element name
=
"
Weather
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:complexType
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
xs:sequence
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
xs:element name
=
"
Date
"
type
=
"
xs:string
"
minOccurs
=
"
0
"
/>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
xs:element name
=
"
Week
"
type
=
"
xs:string
"
minOccurs
=
"
0
"
/>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
xs:element name
=
"
Weather
"
type
=
"
xs:string
"
minOccurs
=
"
0
"
/>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
xs:element name
=
"
Tlow
"
type
=
"
xs:string
"
minOccurs
=
"
0
"
/>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
xs:element name
=
"
Thigh
"
type
=
"
xs:string
"
minOccurs
=
"
0
"
/>
</
xs:sequence
>
</
xs:complexType
>
</
xs:element
>
</
xs:choice
>
</
xs:complexType
>
</
xs:element
>
</
xs:schema
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
diffgr:diffgram xmlns:msdata
=
"
urn:schemas-microsoft-com:xml-msdata
"
xmlns:diffgr
=
"
urn:schemas-microsoft-com:xml-diffgram-v1
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
NewDataSet xmlns
=
""
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
Weather diffgr:id
=
"
Weather1
"
msdata:rowOrder
=
"
0
"
diffgr:hasChanges
=
"
inserted
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Date
>
2008年10月14日
</
Date
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Week
>
星期二(Tue)
</
Week
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Weather
>
Clear
</
Weather
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Tlow
>
16.1
℃
</
Tlow
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Thigh
>
26.7
℃
</
Thigh
>
</
Weather
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
-
<
Weather diffgr:id
=
"
Weather2
"
msdata:rowOrder
=
"
1
"
diffgr:hasChanges
=
"
inserted
"
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Date
>
2008年10月15日
</
Date
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Week
>
星期三(Wed)
</
Week
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Weather
>
Sunny
</
Weather
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Tlow
>
16.7
℃
</
Tlow
>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<
Thigh
>
28.3
℃
</
Thigh
>
</
Weather
>
</
NewDataSet
>
</
diffgr:diffgram
>
</
DataSet
>
写完了!最后希望能给大家带来收获!