I 'm kind of new to VB and .NET, and I'm having trouble especially with trying to setup a weather widget. I'm pulling from Yahoos RSS feeds, storing to an XML file, and then reading from that XML file. The first couple of things pull in fine, but Yahoo's feed sends back basically a LIST of days/temps/highs/lows. (see below)
<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
<channel>
<title>Yahoo! Weather - Lincoln, NE</title>
<link>...</link>
<description>Yahoo! Weather for Lincoln, NE</description>
<language>en-us</language>
<lastBuildDate>Fri, 31 Jan 2014 12:53 pm CST</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Lincoln" region="NE" country="US"/>
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="13" direction="80" speed="7"/>
<yweather:atmosphere humidity="43" visibility="10" pressure="30.08" rising="2"/>
<yweather:astronomy sunrise="7:37 am" sunset="5:43 pm"/>
<image>...</image>
<item>
<title>Conditions for Lincoln, NE at 12:53 pm CST</title>
<geo:lat>40.8</geo:lat>
<geo:long>-96.67</geo:long>
<link>
http://us.rd.yahoo.com/dailynews/rss/weather/Lincoln__NE/*http://weather.yahoo.com/forecast/USNE0283_f.html
</link>
<pubDate>Fri, 31 Jan 2014 12:53 pm CST</pubDate>
<yweather:condition text="Cloudy" code="26" temp="22" date="Fri, 31 Jan 2014 12:53 pm CST"/>
<description>
<![CDATA[...]]>
</description>
<yweather:forecast day="Fri" date="31 Jan 2014" low="18" high="25" text="Few Snow Showers" code="14"/>
<yweather:forecast day="Sat" date="1 Feb 2014" low="5" high="31" text="AM Clouds/PM Sun" code="30"/>
<yweather:forecast day="Sun" date="2 Feb 2014" low="11" high="27" text="Sunny" code="32"/>
<yweather:forecast day="Mon" date="3 Feb 2014" low="18" high="36" text="Partly Cloudy" code="30"/>
<yweather:forecast day="Tue" date="4 Feb 2014" low="-3" high="21" text="Snow Showers" code="14"/>
<guid isPermaLink="false">USNE0283_2014_02_04_7_00_CST</guid>
</item>
</channel>
</rss>
The area I'm having trouble is this
<yweather:forecast day="Fri" date="31 Jan 2014" low="18" high="25" text="Few Snow Showers" code="14"/>
<yweather:forecast day="Sat" date="1 Feb 2014" low="5" high="31" text="AM Clouds/PM Sun" code="30"/>
<yweather:forecast day="Sun" date="2 Feb 2014" low="11" high="27" text="Sunny" code="32"/>
<yweather:forecast day="Mon" date="3 Feb 2014" low="18" high="36" text="Partly Cloudy" code="30"/>
<yweather:forecast day="Tue" date="4 Feb 2014" low="-3" high="21" text="Snow Showers" code="14"/>
As you can see, it gives a list of dates and values back. I'm having trouble reading those values into variables/labels. For example I've been trying
MyDoc.SelectSingleNode("/rss/channel/item/yweather:forecast[day='" + _dayOfweek + "']/@low", nsmgr).InnerText
To try and get the low for each _dayOfWeek -- but I keep getting back XPathExceptions, unclosed strings, so it sounds like the path I take HAS to be a full string with no ' + _dayOfWeek ' - Am I gonig to have to create subroutines for each different day of the week???
Please let me know if you can see anything dumb that I'm doing, here's my code for reference
Public Class CtrlWeatherWidget
ReadOnly _zip = 68508
'In the future, may want to include options to view multiple locations, in which case this won't be read only
Dim _conditions
Dim _dayOfWeek As String
Public Sub Update()
Dim rssurl = "http://xml.weather.yahoo.com/forecastrss?p=" + _zip.ToString()
Dim rssrequest As Net.WebRequest = Net.WebRequest.Create(rssurl)
Dim rssresponse As Net.WebResponse = rssrequest.GetResponse()
Dim rssstream As IO.Stream = rssresponse.GetResponseStream()
Dim rssdoc As New Xml.XmlDocument
rssdoc.Load(rssstream)
Dim nodes As Xml.XmlNodeList
nodes = rssdoc.SelectNodes("/rss/channel")
lblCityState.Text = Replace(nodes.Item(0).SelectSingleNode("title").InnerText, "Yahoo! Weather - ", "")
Dim nsmgr = New Xml.XmlNamespaceManager(rssdoc.NameTable)
nsmgr.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0")
'find the conditions and display the correct image for the current weather
_conditions = rssdoc.SelectSingleNode("/rss/channel/item/yweather:condition/@code", nsmgr).InnerText
picConditions.BackgroundImage = GetConditions()
'get the current days highs and lows and picture
lblCurrentTemp.Text = rssdoc.SelectSingleNode("rss/channel/item/yweather:condition/@temp", nsmgr).InnerText
lblLowNow.Text = rssdoc.SelectSingleNode("/rss/channel/item/yweather:forecast[day='" + _dayOfWeek + "']'/@low", nsmgr).InnerText
'Tabel/Member[Naam='Ghostbullet93']/Kills"
lblHighNow.Text = rssdoc.SelectSingleNode("/rss/channel/item/yweather:forecast[day='" + _dayOfWeek + "']'/@high", nsmgr).InnerText
'set the 3 days in the future information below, and get lows highs, picture
GetDay(1)
lblDayOne.Text = _dayOfWeek
_conditions = rssdoc.SelectSingleNode("rss/channel/yweather:condition/@temp", nsmgr).InnerText
picDayOne.BackgroundImage = GetConditions()
lblHighOne.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("rss/channel/yweather:atmosphere/@humidity", nsmgr).InnerText)
lblLowOne.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("rss/channel/yweather:atmosphere/@humidity", nsmgr).InnerText)
GetDay(2)
lblDayTwo.Text = _dayOfWeek
_conditions = rssdoc.SelectSingleNode("rss/channel/yweather:condition/@temp", nsmgr).InnerText
picDayTwo.BackgroundImage = GetConditions()
lblHighTwo.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("rss/channel/yweather:atmosphere/@humidity", nsmgr).InnerText)
lblLowTwo.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("rss/channel/yweather:atmosphere/@humidity", nsmgr).InnerText)
GetDay(3)
lblDayThree.Text = _dayOfWeek
_conditions = rssdoc.SelectSingleNode("rss/channel/yweather:condition/@temp", nsmgr).InnerText
picDayThree.BackgroundImage = GetConditions()
lblHighThree.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("rss/channel/yweather:atmosphere/@humidity", nsmgr).InnerText)
lblLowThree.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("rss/channel/yweather:atmosphere/@humidity", nsmgr).InnerText)
lblUpdated.Text = String.Format("Last Updated {0}", Replace(nodes.Item(0).SelectSingleNode("rss/channel/item/title").InnerText, "Conditions for ", ""))
End Sub
Public Sub GetDay(ByVal offset As Integer)
Dim day As Integer
day = Date.Now.DayOfWeek
If (day + offset) > 7 Then
day = day + offset
day = day - 7
End If
Select Case day
Case 1
_dayOfWeek = "Mon"
Case 2
_dayOfWeek = "Tue"
Case 3
_dayOfWeek = "Wed"
Case 4
_dayOfWeek = "Thu"
Case 5
_dayOfWeek = "Fri"
Case 6
_dayOfWeek = "Sat"
Case 7
_dayOfWeek = "Sun"
End Select
End Sub
Public Function GetConditions() As Image
If (_conditions >= 0 AndAlso _conditions <= 4) Or (_conditions >= 9 AndAlso _conditions <= 12) Or (_conditions >= 37 AndAlso _conditions <= 40) Or _conditions = 45 Or _conditions = 47 Then
Return My.Resources.raining
ElseIf (_conditions >= 5 AndAlso _conditions <= 8) Or (_conditions >= 13 AndAlso _conditions <= 16) Or (_conditions >= 41 AndAlso _conditions <= 43) Or _conditions = 46 Then
Return My.Resources.snow
ElseIf _conditions = 26 Then
Return My.Resources.overcast_sky
ElseIf _conditions = 27 Or _conditions = 29 Then
Return My.Resources.night_partlycloudy
ElseIf _conditions = 28 Or _conditions = 30 Or _conditions = 44 Then
Return My.Resources.day_partlyCloudy
ElseIf _conditions = 31 Or _conditions = 33 Then
Return My.Resources.moon
ElseIf _conditions = 32 Or _conditions = 34 Or _conditions = 36 Then
Return My.Resources.day_clear
Else
Return My.Resources.overcast_sky
End If
End Function
Private Sub btnUpdate_Click(sender As System.Object, e As EventArgs) Handles btnUpdate.Click
Update()
End Sub
End Class
I found a different way to do it since I'm always looking for just the next 3 days rather than a random/variable number of days
So instead of
MyDoc.SelectSingleNode("/rss/channel/item/yweather:forecast[day='" + _dayOfweek + "']/@low", nsmgr).InnerText
and incrementing the _dayOfWeek, you can skip incrementing, get rid of _dayOfWeek entirely you can actually use
MyDoc.SelectSingleNode("//item/yweather:forecast[1]/@low", nsmgr).InnerText)
and that will allow you to get the low for the 0th day (I guess XML nodes start at 1, not 0)- then you can just iterate over and get the low/high/code for the 1st, 2nd, and third days.
It took me about a day to get this Yahoo RSS feed weather widget running, if anyone wants to see the final code for it, here you go.
Public Sub Update()
Dim rssurl = "http://xml.weather.yahoo.com/forecastrss?p=" + _zip.ToString()
Dim rssrequest As Net.WebRequest = Net.WebRequest.Create(rssurl)
Dim rssresponse As Net.WebResponse = rssrequest.GetResponse()
Dim rssstream As IO.Stream = rssresponse.GetResponseStream()
Dim rssdoc As New Xml.XmlDocument
rssdoc.Load(rssstream)
Dim nodes As Xml.XmlNodeList
nodes = rssdoc.SelectNodes("/rss/channel")
lblCityState.Text = Replace(nodes.Item(0).SelectSingleNode("title").InnerText, "Yahoo! Weather - ", "")
Dim nsmgr = New Xml.XmlNamespaceManager(rssdoc.NameTable)
nsmgr.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0")
'find the conditions and display the correct image for the current weather
_conditions = rssdoc.SelectSingleNode("/rss/channel/item/yweather:condition/@code", nsmgr).InnerText
picConditions.BackgroundImage = GetConditions()
'get the current days highs and lows and picture
lblCurrentTemp.Text = rssdoc.SelectSingleNode("//item/yweather:condition/@temp", nsmgr).InnerText
lblLowNow.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[1]/@low", nsmgr).InnerText)
lblHighNow.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[1]/@high", nsmgr).InnerText)
'set the 3 days in the future information below, and get lows highs, picture
lblDayOne.Text = rssdoc.SelectSingleNode("//item/yweather:forecast[2]/@day", nsmgr).InnerText
_conditions = rssdoc.SelectSingleNode("//item/yweather:forecast[2]/@code", nsmgr).InnerText
picDayOne.BackgroundImage = GetConditions()
lblHighOne.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[2]/@low", nsmgr).InnerText)
lblLowOne.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[2]/@high", nsmgr).InnerText)
lblDayTwo.Text = rssdoc.SelectSingleNode("//item/yweather:forecast[3]/@day", nsmgr).InnerText
_conditions = rssdoc.SelectSingleNode("//item/yweather:forecast[3]/@code", nsmgr).InnerText
picDayTwo.BackgroundImage = GetConditions()
lblHighTwo.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[3]/@high", nsmgr).InnerText)
lblLowTwo.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[3]/@low", nsmgr).InnerText)
lblDayThree.Text = rssdoc.SelectSingleNode("//item/yweather:forecast[4]/@day", nsmgr).InnerText
_conditions = rssdoc.SelectSingleNode("//item/yweather:forecast[4]/@code", nsmgr).InnerText
picDayThree.BackgroundImage = GetConditions()
lblHighThree.Text = String.Format("H: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[4]/@high", nsmgr).InnerText)
lblLowThree.Text = String.Format("L: {0}", rssdoc.SelectSingleNode("//item/yweather:forecast[4]/@low", nsmgr).InnerText)
lblUpdated.Text = String.Format("Updated {0}", rssdoc.SelectSingleNode("//item/yweather:condition/@date", nsmgr).InnerText)
End Sub
Public Function GetConditions() As Image
If (_conditions >= 0 AndAlso _conditions <= 4) Or (_conditions >= 9 AndAlso _conditions <= 12) Or (_conditions >= 37 AndAlso _conditions <= 40) Or _conditions = 45 Or _conditions = 47 Then
Return My.Resources.raining
ElseIf (_conditions >= 5 AndAlso _conditions <= 8) Or (_conditions >= 13 AndAlso _conditions <= 16) Or (_conditions >= 41 AndAlso _conditions <= 43) Or _conditions = 46 Then
Return My.Resources.snow
ElseIf _conditions = 26 Then
Return My.Resources.overcast_sky
ElseIf _conditions = 27 Or _conditions = 29 Then
Return My.Resources.night_partlycloudy
ElseIf _conditions = 28 Or _conditions = 30 Or _conditions = 44 Then
Return My.Resources.day_partlyCloudy
ElseIf _conditions = 31 Or _conditions = 33 Then
Return My.Resources.moon
ElseIf _conditions = 32 Or _conditions = 34 Or _conditions = 36 Then
Return My.Resources.day_clear
Else
Return My.Resources.overcast_sky
End If
End Function
Private Sub btnUpdate_Click(sender As System.Object, e As EventArgs) Handles btnUpdate.Click
Update()
End Sub
Private Sub CtrlWeatherWidget_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Update()
sleepTimer.Start()
End Sub
Private Sub sleepTimer_Tick(sender As System.Object, e As System.EventArgs) Handles sleepTimer.Tick
Update()
End Sub
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments