Click to See Complete Forum and Search --> : Reading XML documents in C#


InsyteMedia
August 26th, 2009, 04:23 AM
Hi Everyone,

Im currently developing a weather application that forecats weather etc...I have ran into a problem with the reading of the XML feed that im using.

Here is an example of an XML feed that is being used:

<?xml version="1.0" ?>
- <weatherdata>
- <weather weatherlocationcode="wc:UKXX0085" weatherlocationname="London, GBR" zipcode="" encodedlocationname="London%2c+GBR" url="http://weather.msn.com/local.aspx?wealocations=wc:UKXX0085&q=London%2c+GBR" imagerelativeurl="http://blst.msn.com/as/wea3/i/en-us/" degreetype="F" provider="Foreca" attribution="Data provided by Foreca" attribution2="© Foreca" lat="51.5178591" long="-0.1022164" timezone="1" alert="">
<current temperature="64" skycode="32" skytext="Clear" date="2009-08-26" day="Wednesday" shortday="Wed" observationtime="09:50:00" observationpoint="London / Heathrow Airport" feelslike="64" humidity="77" windspeed="14" winddisplay="14 mph S" />
<forecast low="61" high="70" skycodeday="11" skytextday="Showers" date="2009-08-26" day="Wednesday" shortday="Wed" precip="80" />
<forecast low="54" high="74" skycodeday="30" skytextday="Partly Cloudy" date="2009-08-27" day="Thursday" shortday="Thu" precip="40" />
<forecast low="50" high="65" skycodeday="39" skytextday="Showers / Clear" date="2009-08-28" day="Friday" shortday="Fri" precip="75" />
<forecast low="49" high="68" skycodeday="28" skytextday="PM Clouds" date="2009-08-29" day="Saturday" shortday="Sat" precip="5" />
<forecast low="59" high="67" skycodeday="30" skytextday="Cloudy / PM Sun" date="2009-08-30" day="Sunday" shortday="Sun" precip="10" />
<toolbar timewindow="60" minversion="1.0.1965.0" />
</weather>
</weatherdata>

Hopefully you can make it out but for each day of the forecast the same element name is used, in this case <forecast>. The problem im having is when i read in the data from the forecast element it seems to only bring back the first instance and last instance of the forecast elements. so effectively im able to get todays weather and the weather 4 days from now as thats the last entry. I use the following code in my application:

else if ((reader.NodeType == XmlNodeType.Element) && ((reader.Name == "forecast")
&& (firstForecastDone == false)))
{
firstForecastDone = true;
reader.MoveToAttribute("high");
int.TryParse(reader.Value, out MaxTemp);
currentWeatherReport.MaxTemperatureForecast = MaxTemp;
reader.MoveToAttribute("low");
int.TryParse(reader.Value, out MinTemp);
currentWeatherReport.MinTemperatureForecast = MinTemp;

reader.MoveToAttribute("day");
currentWeatherReport.Day1 = reader.Value;

I then repeat this code incrementing the values by 1 hoping that it would simply move to the next instance of the forecast element giving me the next days weather but it does not, as i mentioned it only brings back the current days weather and the weather 4 days from now.

Does anyone know how i might code this so that its possible to read each element seperately?

vcdebugger
August 26th, 2009, 07:04 AM
Try to put the code in the .. tags for better readibility and also put the code where you are incrementing the counter.

InsyteMedia
August 26th, 2009, 08:24 AM
This is the code I have so far far for my weather report:


public WeatherReport.WeatherReport GetWeatherReport(string location)
{
WeatherReport.WeatherReport currentWeatherReport = new WeatherReport.WeatherReport();

// URL corresponding to the MSN REST Web Service - see how the locationCode
// is passed in parameter to this URL.
// The XMLTextReader opens up the URL and receives the XML returned by th server
// http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:USWA0367
string feedUrl = "http://weather.service.msn.com/data.aspx?src=vista&wealocations=" + location;
XmlTextReader reader = new XmlTextReader(feedUrl);
bool firstForecastDone = false;
string skyImagesRelativeUrl = "Images/";
int MaxTemp, MinTemp, CurrentTemp, FeelsLike, Humidity, SkyCode, SkyCode4, MaxTemp4, MinTemp4, Precip4;

try
{
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "weather"))
{
reader.MoveToAttribute("weatherlocationname");
currentWeatherReport.Location = reader.Value;

reader.MoveToAttribute("lat");
currentWeatherReport.Lattitude = reader.Value;

reader.MoveToAttribute("long");
currentWeatherReport.Longitude = reader.Value;
}
else if ((reader.NodeType == XmlNodeType.Element) && ((reader.Name == "forecast")
&& (firstForecastDone == false)))
{
firstForecastDone = true;
reader.MoveToAttribute("high");
int.TryParse(reader.Value, out MaxTemp);
currentWeatherReport.MaxTemperatureForecast = MaxTemp;
reader.MoveToAttribute("low");
int.TryParse(reader.Value, out MinTemp);
currentWeatherReport.MinTemperatureForecast = MinTemp;

reader.MoveToAttribute("day");
currentWeatherReport.Day1 = reader.Value;

}

else if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "forecast"))
{
reader.MoveToAttribute("day");
currentWeatherReport.Day4 = reader.Value;

reader.MoveToAttribute("skytextday");
currentWeatherReport.SkyText4 = reader.Value;

reader.MoveToAttribute("high");
int.TryParse(reader.Value, out MaxTemp4);
currentWeatherReport.MaxTemperatureForecast4 = MaxTemp4;
reader.MoveToAttribute("low");
int.TryParse(reader.Value, out MinTemp4);
currentWeatherReport.MinTemperatureForecast4 = MinTemp4;

reader.MoveToAttribute("precip");
int.TryParse(reader.Value, out Precip4);
currentWeatherReport.Precipitation4 = Precip4;

reader.MoveToAttribute("skycodeday");
int.TryParse(reader.Value, out SkyCode4);
currentWeatherReport.SkyCode4 = SkyCode4;
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode4 + ".gif";
currentWeatherReport.SkyImage4 = new Bitmap(fileName);

}

else if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "forecast"))
{
reader.MoveToAttribute("day");
currentWeatherReport.Day3 = reader.Value;

}

else if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "current"))
{
reader.MoveToAttribute("temperature");
int.TryParse(reader.Value, out CurrentTemp);
currentWeatherReport.CurrentTemperature = CurrentTemp;

reader.MoveToAttribute("feelslike");
int.TryParse(reader.Value, out FeelsLike);
currentWeatherReport.FeelsLikeTemperature = FeelsLike;

reader.MoveToAttribute("humidity");
int.TryParse(reader.Value, out Humidity);
currentWeatherReport.Humidity = Humidity;

reader.MoveToAttribute("skytext");
currentWeatherReport.SkyText = reader.Value;

reader.MoveToAttribute("skycode");
int.TryParse(reader.Value, out SkyCode);
currentWeatherReport.SkyCode = SkyCode;
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);

reader.MoveToAttribute("observationtime");
char[] splitter = ":".ToCharArray();
string[] hourMinuteSecond = reader.Value.Split(splitter);
int hour, minute, second;
int.TryParse(hourMinuteSecond[0], out hour);
int.TryParse(hourMinuteSecond[1], out minute);
int.TryParse(hourMinuteSecond[2], out second);

reader.MoveToAttribute("date");
splitter = "-".ToCharArray();
string[] yearMonthDay = reader.Value.Split(splitter);
int year, month, day;
int.TryParse(yearMonthDay[0], out year);
int.TryParse(yearMonthDay[1], out month);
int.TryParse(yearMonthDay[2], out day);
currentWeatherReport.LastUpdate = new DateTime(year, month, day, hour, minute, second);

reader.MoveToAttribute("winddisplay");
currentWeatherReport.WindDisplay = reader.Value;

reader.MoveToAttribute("observationpoint");
currentWeatherReport.Observation = reader.Value;

}
}
return currentWeatherReport;
}
catch (Exception ex)
{
throw ex;
}
}


Im simply adding new variables myself such as Day1, Day2 etc. I know there is a way to goto the next attribute but is there a way to go to the next element or something like that. Would have been much easier if the name of the elements were different.

dannystommen
August 26th, 2009, 09:23 AM
I woud use Xpath to select the correct XmlNodes. When you have done that, you can simply loop through the XmlNodeList

Try next

XmlDocument doc = new XmlDocument();
doc.Load("http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:USWA0367");

XmlNodeList forecast_list = doc.DocumentElement.SelectNodes("weather/forecast");
foreach (XmlNode forecast in forecast_list) {
string day = forecast.Attributes["day"].Value;
}

InsyteMedia
August 26th, 2009, 09:42 AM
Ok ok, I like your thinking. This does work and it brings back each day. How would I then store each of these values.

I.e the first value it returns I want to be stored as Day1 and then the next value would be stored as Day2 etc until it has no more attributes to store.

dannystommen
August 26th, 2009, 09:44 AM
can you post the code how your WeatherReport class looks like?

InsyteMedia
August 26th, 2009, 10:08 AM
This is what i currently have in my WeatherReport class looks like:


namespace WeatherReport
{
public class WeatherReport
{
private int currentTempValue;
public int CurrentTemperature {
get
{
return currentTempValue;
}

set
{
currentTempValue = value;
}
}

private int feelsLikeTemperatureValue;
public int FeelsLikeTemperature
{
get
{
return feelsLikeTemperatureValue;
}

set
{
feelsLikeTemperatureValue = value;
}
}

private int humidityValue;
public int Humidity
{
get
{
return humidityValue;
}

set
{
humidityValue = value;
}
}

private DateTime lastUpdateValue;
public DateTime LastUpdate
{
get
{
return lastUpdateValue;
}

set
{
lastUpdateValue = value;
}
}

private string locationValue;
public string Location
{
get
{
return locationValue;
}

set
{
locationValue = value;
}
}

private int skyCodeValue;
public int SkyCode
{
get
{
return skyCodeValue;
}

set
{
skyCodeValue = value;
}
}

private string skyTextValue;
public string SkyText
{
get
{
return skyTextValue;
}

set
{
skyTextValue = value;
}
}

private Bitmap skyImageValue;
public Bitmap SkyImage
{
get
{
return skyImageValue;
}

set
{
skyImageValue = value;
}
}

private int minTemperatureForecastValue;
public int MinTemperatureForecast
{
get
{
return minTemperatureForecastValue;
}

set
{
minTemperatureForecastValue = value;
}
}


private int maxTemperatureForecastValue;
public int MaxTemperatureForecast
{
get
{
return maxTemperatureForecastValue;
}

set
{
maxTemperatureForecastValue = value;
}
}

private string locationCodeValue;
public string LocationCodeValue
{
get
{
return locationCodeValue;
}

set
{
locationCodeValue = value;
}
}

private string WindDisplayValue;
public string WindDisplay
{
get
{
return WindDisplayValue;
}

set
{
WindDisplayValue = value;
}
}

private string LattitudeValue;
public string Lattitude
{
get
{
return LattitudeValue;
}

set
{
LattitudeValue = value;
}
}

private string LongitudeValue;
public string Longitude
{
get
{
return LongitudeValue;
}

set
{
LongitudeValue = value;
}
}

private string ObservationValue;
public string Observation
{
get
{
return ObservationValue;
}

set
{
ObservationValue = value;
}
}

private string Day1Value;
public string Day1
{
get
{
return Day1Value;
}

set
{
Day1Value = value;
}
}

private string Day4Value;
public string Day4
{
get
{
return Day4Value;
}

set
{
Day4Value = value;
}
}

private string Day3Value;
public string Day3
{
get
{
return Day3Value;
}

set
{
Day3Value = value;
}
}

private int skyCode4Value;
public int SkyCode4
{
get
{
return skyCode4Value;
}

set
{
skyCode4Value = value;
}
}

private Bitmap skyImage4Value;
public Bitmap SkyImage4
{
get
{
return skyImage4Value;
}

set
{
skyImage4Value = value;
}
}

private string SkyText4Value;
public string SkyText4
{
get
{
return SkyText4Value;
}

set
{
SkyText4Value = value;
}
}

private int minTemperatureForecast4Value;
public int MinTemperatureForecast4
{
get
{
return minTemperatureForecast4Value;
}

set
{
minTemperatureForecast4Value = value;
}
}


private int maxTemperatureForecast4Value;
public int MaxTemperatureForecast4
{
get
{
return maxTemperatureForecast4Value;
}

set
{
maxTemperatureForecast4Value = value;
}
}

private int Precipitation4Value;
public int Precipitation4
{
get
{
return Precipitation4Value;
}

set
{
Precipitation4Value = value;
}
}
}
}

dannystommen
August 26th, 2009, 10:31 AM
It is not really a nice way to code properties like 'Day1' to 'Day4'. What will happens if the weatherreport you recieve contains 5 days instead of 4?

I would use an List<T> to save the forecasts of each day


public class ForeCast{
public string Day{get;set;}
public int MaxTemperature{get;set;}
//and all order forecast element of one day
}

...

public class WeatherReport{
private List<ForeCast> foreCast_list = new List<ForeCast>();
public List<ForeCast> ForeCast_list {
get{ return foreCast_list; }
set { foreCast_list = value; }
}

...

XmlDocument doc = new XmlDocument();
doc.Load("http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:USWA0367");

XmlNodeList forecast_list = doc.DocumentElement.SelectNodes("weather/forecast");
WeatherReport report = new WeatherReport();
foreach (XmlNode forecast in forecast_list) {
ForeCast f = new ForeCast();
f.Day = forecast.Attributes["day"].Value;
f.MaxTemperature = Convert.ToInt32(forecast.Attributes["high"].Value);
report.ForeCast_list.Add(f);
}
}


Now you can loop through the report.ForeCast_list to show the data of each day

InsyteMedia
August 26th, 2009, 10:56 AM
How do I display that data on my form?

Currently I have a number of labels on my main form which display all of the weather details using a WeatherReportBindingSource.

I would like to have each attribute binded to a label so that i can move the data around on my form.

InsyteMedia
August 26th, 2009, 10:58 AM
Also the XML feed is fixed, it will only ever contain 5 forecast elements

dannystommen
August 27th, 2009, 02:07 AM
You can use Reflection to find the correct property


WeatherReport report = new WeatherReport();
int daynumber = 1;
foreach (XmlNode forecast in forecast_list) {
PropertyInfo day = report.GetType().GetProperty("Day" + daynumber);
day.SetValue(report, forecast.Attributes["day"].Value, null);

daynumber++;
}


Now, all days (Day1, Day2 ... ) will have the correct value

InsyteMedia
August 27th, 2009, 02:55 AM
Ok, does this replace the code that you gave me in the previous post? i.e. does that code replace the code below or is it used somewhere else?

WeatherReport report = new WeatherReport();
foreach (XmlNode forecast in forecast_list) {
ForeCast f = new ForeCast();
f.Day = forecast.Attributes["day"].Value;
f.MaxTemperature = Convert.ToInt32(forecast.Attributes["high"].Value);
report.ForeCast_list.Add(f);
}

dannystommen
August 27th, 2009, 03:00 AM
Also the XML feed is fixed, it will only ever contain 5 forecast elements

I assumed you would like to use the WeatherReport class like you have it now, thus with the Day1, Day2... properties. If so, use the code form my previous post that uses Reflection.

WeatherReport report = new WeatherReport();
int daynumber = 1;
foreach (XmlNode forecast in forecast_list) {
PropertyInfo day = report.GetType().GetProperty("Day" + daynumber);
day.SetValue(report, forecast.Attributes["day"].Value, null);

daynumber++;
}


If you want to use the WeatherReport class like I suggested (with the List<ForeCast> property), then use the code you just posted

WeatherReport report = new WeatherReport();
foreach (XmlNode forecast in forecast_list) {
ForeCast f = new ForeCast();
f.Day = forecast.Attributes["day"].Value;
f.MaxTemperature = Convert.ToInt32(forecast.Attributes["high"].Value);
report.ForeCast_list.Add(f);
}

InsyteMedia
August 27th, 2009, 03:30 AM
Thanks a lot for this, its much appreciated. I will give your suggestions a try and see how they work.

Thanks

InsyteMedia
August 27th, 2009, 08:06 AM
Hiya, Ive ran into a problem when retreiving the min and max values from the feed now.

When using the following code you provided


PropertyInfo high = currentWeatherReport.GetType().GetProperty("MaxTemperatureForecast" + maxTempnumber);
high.SetValue(currentWeatherReport, forecast.Attributes["high"].Value, null);
maxTempnumber++;


I need to convert the value into an integer before saving the value, how can i do that. Ive tried using the convert.toint32 function but it doesnt seem to work, unless ive placed it in the wrong place. As the code is above it saves it as a string but i need an int.

Thanks

dannystommen
August 27th, 2009, 08:12 AM
try

high.SetValue(currentWeatherReport, Convert.ToInt32(forecast.Attributes["high"].Value), null);

InsyteMedia
August 27th, 2009, 09:13 AM
Ok that works nicely, Thanks.

The last problem ive encountered is generating the URL for the image i use for each day.

Ive got the following code


PropertyInfo skycodeday = currentWeatherReport.GetType().GetProperty("SkyCode" + skycodenumber);
skycodeday.SetValue(currentWeatherReport, forecast.Attributes["SkyCode"].Value, null);
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);
skycodenumber++;


so this works in terms of getting the correct SkyCode value and it stores them with no problem. But i now need to generate a URL based on the day number

so it generates a URL which is : skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif"

so this now needs to be something like currentWeatherReport.SkyCode + skycodenumber + ".gif" but im not sure.

also it will then need to save as SkyImage1-5 as before, how might i do this, in the same way as the others?

eclipsed4utoo
August 27th, 2009, 10:34 AM
just for the hell of it, if you are using .Net 3.5, you can use LINQ-To-XML..


XDocument doc = XDocument.Load("http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:USWA0367");

var query = from e in doc.Root.Descendants("weather")
select new WeatherReport
{
CurrentTemperature = int.Parse(e.Element("current").Attribute("temperature").Value),
FeelsLikeTemperature = int.Parse(e.Element("current").Attribute("feelslike").Value),
Day1 = e.Descendants("forecast").Attributes("day").First().Value,
Day3 = e.Descendants("forecast").Attributes("day").Skip(2).First().Value,
Day4 = e.Descendants("forecast").Attributes("day").Skip(3).First().Value,
};

InsyteMedia
August 27th, 2009, 02:07 PM
Thanks for that, i may look into that after ive finished.

If anyone has any ideas on my other problem let me know

InsyteMedia
August 28th, 2009, 03:13 AM
Anyone any ideas on the below?

Ok that works nicely, Thanks.

The last problem ive encountered is generating the URL for the image i use for each day.

Ive got the following code


PropertyInfo skycodeday = currentWeatherReport.GetType().GetProperty("SkyCode" + skycodenumber);
skycodeday.SetValue(currentWeatherReport, forecast.Attributes["SkyCode"].Value, null);
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);
skycodenumber++;


so this works in terms of getting the correct SkyCode value and it stores them with no problem. But i now need to generate a URL based on the day number

so it generates a URL which is : skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif"

so this now needs to be something like currentWeatherReport.SkyCode + skycodenumber + ".gif" but im not sure.

also it will then need to save as SkyImage1-5 as before, how might i do this, in the same way as the others?

dglienna
August 28th, 2009, 09:01 PM
Show us the results of:

What you HAVE
What you WANT

and

What the current strings are.

InsyteMedia
September 2nd, 2009, 08:03 AM
Ok, so far when the refresh button is used the following code is run


public WeatherReport.WeatherReport GetWeatherReport(string location)
{
WeatherReport.WeatherReport currentWeatherReport = new WeatherReport.WeatherReport();

// URL corresponding to the MSN REST Web Service - see how the locationCode is passed in parameter to this URL.
// The XMLTextReader opens up the URL and receives the XML returned by the server
// http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:USWA0367
string feedUrl = "http://weather.service.msn.com/data.aspx?src=vista&wealocations=" + location;
XmlTextReader reader = new XmlTextReader(feedUrl);
bool firstForecastDone = false;
string skyImagesRelativeUrl = "Images/";
int MaxTemp, MinTemp, CurrentTemp, FeelsLike, Humidity, SkyCode;

try
{
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "weather"))
{
reader.MoveToAttribute("weatherlocationname");
currentWeatherReport.Location = reader.Value;

reader.MoveToAttribute("lat");
currentWeatherReport.Lattitude = reader.Value;

reader.MoveToAttribute("long");
currentWeatherReport.Longitude = reader.Value;
}
else if ((reader.NodeType == XmlNodeType.Element) && ((reader.Name == "forecast")
&& (firstForecastDone == false)))
{
firstForecastDone = true;
reader.MoveToAttribute("high");
int.TryParse(reader.Value, out MaxTemp);
currentWeatherReport.MaxTemperatureForecast = MaxTemp;
reader.MoveToAttribute("low");
int.TryParse(reader.Value, out MinTemp);
currentWeatherReport.MinTemperatureForecast = MinTemp;
}

else if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "current"))
{
reader.MoveToAttribute("temperature");
int.TryParse(reader.Value, out CurrentTemp);
currentWeatherReport.CurrentTemperature = CurrentTemp;

reader.MoveToAttribute("feelslike");
int.TryParse(reader.Value, out FeelsLike);
currentWeatherReport.FeelsLikeTemperature = FeelsLike;

reader.MoveToAttribute("humidity");
int.TryParse(reader.Value, out Humidity);
currentWeatherReport.Humidity = Humidity;

reader.MoveToAttribute("skytext");
currentWeatherReport.SkyText = reader.Value;

reader.MoveToAttribute("skycode");
int.TryParse(reader.Value, out SkyCode);
currentWeatherReport.SkyCode = SkyCode;
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);

reader.MoveToAttribute("observationtime");
char[] splitter = ":".ToCharArray();
string[] hourMinuteSecond = reader.Value.Split(splitter);
int hour, minute, second;
int.TryParse(hourMinuteSecond[0], out hour);
int.TryParse(hourMinuteSecond[1], out minute);
int.TryParse(hourMinuteSecond[2], out second);

reader.MoveToAttribute("date");
splitter = "-".ToCharArray();
string[] yearMonthDay = reader.Value.Split(splitter);
int year, month, day;
int.TryParse(yearMonthDay[0], out year);
int.TryParse(yearMonthDay[1], out month);
int.TryParse(yearMonthDay[2], out day);
currentWeatherReport.LastUpdate = new DateTime(year, month, day, hour, minute, second);

reader.MoveToAttribute("winddisplay");
currentWeatherReport.WindDisplay = reader.Value;

reader.MoveToAttribute("observationpoint");
currentWeatherReport.Observation = reader.Value;

}

XmlDocument doc = new XmlDocument();
doc.Load(feedUrl);

XmlNodeList forecast_list = doc.DocumentElement.SelectNodes("weather/forecast");
int daynumber = 1;
int precipnumber = 1;
int skytextnumber = 1;
int minTempnumber = 1;
int maxTempnumber = 1;
foreach (XmlNode forecast in forecast_list)
{
PropertyInfo day = currentWeatherReport.GetType().GetProperty("Day" + daynumber);
day.SetValue(currentWeatherReport, forecast.Attributes["day"].Value, null);
daynumber++;

PropertyInfo skytextday = currentWeatherReport.GetType().GetProperty("SkyText" + skytextnumber);
skytextday.SetValue(currentWeatherReport, forecast.Attributes["skytextday"].Value, null);
skytextnumber++;

PropertyInfo precip = currentWeatherReport.GetType().GetProperty("Precipitation" + precipnumber);
precip.SetValue(currentWeatherReport, forecast.Attributes["precip"].Value, null);
precipnumber++;

PropertyInfo high = currentWeatherReport.GetType().GetProperty("MaxTemperatureForecast" + maxTempnumber);
high.SetValue(currentWeatherReport, Convert.ToInt32(forecast.Attributes["high"].Value), null);
maxTempnumber++;

PropertyInfo low = currentWeatherReport.GetType().GetProperty("MinTemperatureForecast" + minTempnumber);
low.SetValue(currentWeatherReport, Convert.ToInt32(forecast.Attributes["low"].Value), null);
minTempnumber++;

}
}
return currentWeatherReport;
}
catch (Exception ex)
{
throw ex;
}
}


This stores all of the values it gets in here:


public class WeatherReport
{
private int currentTempValue;
public int CurrentTemperature {
get
{
return currentTempValue;
}

set
{
currentTempValue = value;
}
}

private int feelsLikeTemperatureValue;
public int FeelsLikeTemperature
{
get
{
return feelsLikeTemperatureValue;
}

set
{
feelsLikeTemperatureValue = value;
}
}

private int humidityValue;
public int Humidity
{
get
{
return humidityValue;
}

set
{
humidityValue = value;
}
}

private DateTime lastUpdateValue;
public DateTime LastUpdate
{
get
{
return lastUpdateValue;
}

set
{
lastUpdateValue = value;
}
}

private string locationValue;
public string Location
{
get
{
return locationValue;
}

set
{
locationValue = value;
}
}

private int skyCodeValue;
public int SkyCode
{
get
{
return skyCodeValue;
}

set
{
skyCodeValue = value;
}
}

private int skyCode1Value;
public int SkyCode1
{
get
{
return skyCode1Value;
}

set
{
skyCode1Value = value;
}
}
private int skyCode2Value;
public int SkyCode2
{
get
{
return skyCode2Value;
}

set
{
skyCode2Value = value;
}
}

private int skyCode3Value;
public int SkyCode3
{
get
{
return skyCode3Value;
}

set
{
skyCode3Value = value;
}
}

private int skyCode4Value;
public int SkyCode4
{
get
{
return skyCode4Value;
}

set
{
skyCode4Value = value;
}
}

private string skyTextValue;
public string SkyText
{
get
{
return skyTextValue;
}

set
{
skyTextValue = value;
}
}

private string SkyText1Value;
public string SkyText1
{
get
{
return SkyText1Value;
}

set
{
SkyText1Value = value;
}
}

private string SkyText2Value;
public string SkyText2
{
get
{
return SkyText2Value;
}

set
{
SkyText2Value = value;
}
}

private string SkyText3Value;
public string SkyText3
{
get
{
return SkyText3Value;
}

set
{
SkyText3Value = value;
}
}

private string SkyText4Value;
public string SkyText4
{
get
{
return SkyText4Value;
}

set
{
SkyText4Value = value;
}
}

private string SkyText5Value;
public string SkyText5
{
get
{
return SkyText5Value;
}

set
{
SkyText5Value = value;
}
}

private Bitmap skyImageValue;
public Bitmap SkyImage
{
get
{
return skyImageValue;
}

set
{
skyImageValue = value;
}
}

private int minTemperatureForecastValue;
public int MinTemperatureForecast
{
get
{
return minTemperatureForecastValue;
}

set
{
minTemperatureForecastValue = value;
}
}


private int maxTemperatureForecastValue;
public int MaxTemperatureForecast
{
get
{
return maxTemperatureForecastValue;
}

set
{
maxTemperatureForecastValue = value;
}
}

private string locationCodeValue;
public string LocationCodeValue
{
get
{
return locationCodeValue;
}

set
{
locationCodeValue = value;
}
}

private string WindDisplayValue;
public string WindDisplay
{
get
{
return WindDisplayValue;
}

set
{
WindDisplayValue = value;
}
}

private string LattitudeValue;
public string Lattitude
{
get
{
return LattitudeValue;
}

set
{
LattitudeValue = value;
}
}

private string LongitudeValue;
public string Longitude
{
get
{
return LongitudeValue;
}

set
{
LongitudeValue = value;
}
}

private string ObservationValue;
public string Observation
{
get
{
return ObservationValue;
}

set
{
ObservationValue = value;
}
}

private string Day1Value;
public string Day1
{
get
{
return Day1Value;
}

set
{
Day1Value = value;
}
}

private string Day2Value;
public string Day2
{
get
{
return Day2Value;
}

set
{
Day2Value = value;
}
}

private string Day3Value;
public string Day3
{
get
{
return Day3Value;
}

set
{
Day3Value = value;
}
}

private string Day4Value;
public string Day4
{
get
{
return Day4Value;
}

set
{
Day4Value = value;
}
}

private string Day5Value;
public string Day5
{
get
{
return Day5Value;
}

set
{
Day5Value = value;
}
}

private Bitmap skyImage1Value;
public Bitmap SkyImage1
{
get
{
return skyImage1Value;
}

set
{
skyImage1Value = value;
}
}

private Bitmap skyImage2Value;
public Bitmap SkyImage2
{
get
{
return skyImage2Value;
}

set
{
skyImage2Value = value;
}
}

private Bitmap skyImage3Value;
public Bitmap SkyImage3
{
get
{
return skyImage3Value;
}

set
{
skyImage3Value = value;
}
}

private Bitmap skyImage4Value;
public Bitmap SkyImage4
{
get
{
return skyImage4Value;
}

set
{
skyImage4Value = value;
}
}

private Bitmap skyImage5Value;
public Bitmap SkyImage5
{
get
{
return skyImage5Value;
}

set
{
skyImage5Value = value;
}
}

private List<ForeCast> foreCast_list = new List<ForeCast>();
public List<ForeCast> ForeCast_list
{
get
{
return foreCast_list;
}

set
{
foreCast_list = value;
}
}
}


Now for the current day the following code is used to get the skycode and the image:


reader.MoveToAttribute("skycode");
int.TryParse(reader.Value, out SkyCode);
currentWeatherReport.SkyCode = SkyCode;
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);


this stores the skycode and add the URL to the images folder to it so in the end it would say \images\12.gif and that would be used to get the image.

im now doing a forecast from 4 additional days and with the other attributes ive saved them as attribute1, attribute2..., not the best way i know but its the method ive done.

i now want to uses the same kind of code as above but instead of saving it as SkyImage i want it to be SkyImage1, SkyImage2......

codeguy03
September 3rd, 2009, 06:30 PM
I ve tried this for something similar I am doing is and even though it works perfect I wanted to was there a more efficient way of achieving the same result? I was ways told that a lot of if and else statements isn't good to do.


Ok, so far when the refresh button is used the following code is run


public WeatherReport.WeatherReport GetWeatherReport(string location)
{
WeatherReport.WeatherReport currentWeatherReport = new WeatherReport.WeatherReport();

// URL corresponding to the MSN REST Web Service - see how the locationCode is passed in parameter to this URL.
// The XMLTextReader opens up the URL and receives the XML returned by the server
// http://weather.service.msn.com/data.aspx?src=vista&wealocations=wc:USWA0367
string feedUrl = "http://weather.service.msn.com/data.aspx?src=vista&wealocations=" + location;
XmlTextReader reader = new XmlTextReader(feedUrl);
bool firstForecastDone = false;
string skyImagesRelativeUrl = "Images/";
int MaxTemp, MinTemp, CurrentTemp, FeelsLike, Humidity, SkyCode;

try
{
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "weather"))
{
reader.MoveToAttribute("weatherlocationname");
currentWeatherReport.Location = reader.Value;

reader.MoveToAttribute("lat");
currentWeatherReport.Lattitude = reader.Value;

reader.MoveToAttribute("long");
currentWeatherReport.Longitude = reader.Value;
}
else if ((reader.NodeType == XmlNodeType.Element) && ((reader.Name == "forecast")
&& (firstForecastDone == false)))
{
firstForecastDone = true;
reader.MoveToAttribute("high");
int.TryParse(reader.Value, out MaxTemp);
currentWeatherReport.MaxTemperatureForecast = MaxTemp;
reader.MoveToAttribute("low");
int.TryParse(reader.Value, out MinTemp);
currentWeatherReport.MinTemperatureForecast = MinTemp;
}

else if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "current"))
{
reader.MoveToAttribute("temperature");
int.TryParse(reader.Value, out CurrentTemp);
currentWeatherReport.CurrentTemperature = CurrentTemp;

reader.MoveToAttribute("feelslike");
int.TryParse(reader.Value, out FeelsLike);
currentWeatherReport.FeelsLikeTemperature = FeelsLike;

reader.MoveToAttribute("humidity");
int.TryParse(reader.Value, out Humidity);
currentWeatherReport.Humidity = Humidity;

reader.MoveToAttribute("skytext");
currentWeatherReport.SkyText = reader.Value;

reader.MoveToAttribute("skycode");
int.TryParse(reader.Value, out SkyCode);
currentWeatherReport.SkyCode = SkyCode;
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);

reader.MoveToAttribute("observationtime");
char[] splitter = ":".ToCharArray();
string[] hourMinuteSecond = reader.Value.Split(splitter);
int hour, minute, second;
int.TryParse(hourMinuteSecond[0], out hour);
int.TryParse(hourMinuteSecond[1], out minute);
int.TryParse(hourMinuteSecond[2], out second);

reader.MoveToAttribute("date");
splitter = "-".ToCharArray();
string[] yearMonthDay = reader.Value.Split(splitter);
int year, month, day;
int.TryParse(yearMonthDay[0], out year);
int.TryParse(yearMonthDay[1], out month);
int.TryParse(yearMonthDay[2], out day);
currentWeatherReport.LastUpdate = new DateTime(year, month, day, hour, minute, second);

reader.MoveToAttribute("winddisplay");
currentWeatherReport.WindDisplay = reader.Value;

reader.MoveToAttribute("observationpoint");
currentWeatherReport.Observation = reader.Value;

}

XmlDocument doc = new XmlDocument();
doc.Load(feedUrl);

XmlNodeList forecast_list = doc.DocumentElement.SelectNodes("weather/forecast");
int daynumber = 1;
int precipnumber = 1;
int skytextnumber = 1;
int minTempnumber = 1;
int maxTempnumber = 1;
foreach (XmlNode forecast in forecast_list)
{
PropertyInfo day = currentWeatherReport.GetType().GetProperty("Day" + daynumber);
day.SetValue(currentWeatherReport, forecast.Attributes["day"].Value, null);
daynumber++;

PropertyInfo skytextday = currentWeatherReport.GetType().GetProperty("SkyText" + skytextnumber);
skytextday.SetValue(currentWeatherReport, forecast.Attributes["skytextday"].Value, null);
skytextnumber++;

PropertyInfo precip = currentWeatherReport.GetType().GetProperty("Precipitation" + precipnumber);
precip.SetValue(currentWeatherReport, forecast.Attributes["precip"].Value, null);
precipnumber++;

PropertyInfo high = currentWeatherReport.GetType().GetProperty("MaxTemperatureForecast" + maxTempnumber);
high.SetValue(currentWeatherReport, Convert.ToInt32(forecast.Attributes["high"].Value), null);
maxTempnumber++;

PropertyInfo low = currentWeatherReport.GetType().GetProperty("MinTemperatureForecast" + minTempnumber);
low.SetValue(currentWeatherReport, Convert.ToInt32(forecast.Attributes["low"].Value), null);
minTempnumber++;

}
}
return currentWeatherReport;
}
catch (Exception ex)
{
throw ex;
}
}


This stores all of the values it gets in here:


public class WeatherReport
{
private int currentTempValue;
public int CurrentTemperature {
get
{
return currentTempValue;
}

set
{
currentTempValue = value;
}
}

private int feelsLikeTemperatureValue;
public int FeelsLikeTemperature
{
get
{
return feelsLikeTemperatureValue;
}

set
{
feelsLikeTemperatureValue = value;
}
}

private int humidityValue;
public int Humidity
{
get
{
return humidityValue;
}

set
{
humidityValue = value;
}
}

private DateTime lastUpdateValue;
public DateTime LastUpdate
{
get
{
return lastUpdateValue;
}

set
{
lastUpdateValue = value;
}
}

private string locationValue;
public string Location
{
get
{
return locationValue;
}

set
{
locationValue = value;
}
}

private int skyCodeValue;
public int SkyCode
{
get
{
return skyCodeValue;
}

set
{
skyCodeValue = value;
}
}

private int skyCode1Value;
public int SkyCode1
{
get
{
return skyCode1Value;
}

set
{
skyCode1Value = value;
}
}
private int skyCode2Value;
public int SkyCode2
{
get
{
return skyCode2Value;
}

set
{
skyCode2Value = value;
}
}

private int skyCode3Value;
public int SkyCode3
{
get
{
return skyCode3Value;
}

set
{
skyCode3Value = value;
}
}

private int skyCode4Value;
public int SkyCode4
{
get
{
return skyCode4Value;
}

set
{
skyCode4Value = value;
}
}

private string skyTextValue;
public string SkyText
{
get
{
return skyTextValue;
}

set
{
skyTextValue = value;
}
}

private string SkyText1Value;
public string SkyText1
{
get
{
return SkyText1Value;
}

set
{
SkyText1Value = value;
}
}

private string SkyText2Value;
public string SkyText2
{
get
{
return SkyText2Value;
}

set
{
SkyText2Value = value;
}
}

private string SkyText3Value;
public string SkyText3
{
get
{
return SkyText3Value;
}

set
{
SkyText3Value = value;
}
}

private string SkyText4Value;
public string SkyText4
{
get
{
return SkyText4Value;
}

set
{
SkyText4Value = value;
}
}

private string SkyText5Value;
public string SkyText5
{
get
{
return SkyText5Value;
}

set
{
SkyText5Value = value;
}
}

private Bitmap skyImageValue;
public Bitmap SkyImage
{
get
{
return skyImageValue;
}

set
{
skyImageValue = value;
}
}

private int minTemperatureForecastValue;
public int MinTemperatureForecast
{
get
{
return minTemperatureForecastValue;
}

set
{
minTemperatureForecastValue = value;
}
}


private int maxTemperatureForecastValue;
public int MaxTemperatureForecast
{
get
{
return maxTemperatureForecastValue;
}

set
{
maxTemperatureForecastValue = value;
}
}

private string locationCodeValue;
public string LocationCodeValue
{
get
{
return locationCodeValue;
}

set
{
locationCodeValue = value;
}
}

private string WindDisplayValue;
public string WindDisplay
{
get
{
return WindDisplayValue;
}

set
{
WindDisplayValue = value;
}
}

private string LattitudeValue;
public string Lattitude
{
get
{
return LattitudeValue;
}

set
{
LattitudeValue = value;
}
}

private string LongitudeValue;
public string Longitude
{
get
{
return LongitudeValue;
}

set
{
LongitudeValue = value;
}
}

private string ObservationValue;
public string Observation
{
get
{
return ObservationValue;
}

set
{
ObservationValue = value;
}
}

private string Day1Value;
public string Day1
{
get
{
return Day1Value;
}

set
{
Day1Value = value;
}
}

private string Day2Value;
public string Day2
{
get
{
return Day2Value;
}

set
{
Day2Value = value;
}
}

private string Day3Value;
public string Day3
{
get
{
return Day3Value;
}

set
{
Day3Value = value;
}
}

private string Day4Value;
public string Day4
{
get
{
return Day4Value;
}

set
{
Day4Value = value;
}
}

private string Day5Value;
public string Day5
{
get
{
return Day5Value;
}

set
{
Day5Value = value;
}
}

private Bitmap skyImage1Value;
public Bitmap SkyImage1
{
get
{
return skyImage1Value;
}

set
{
skyImage1Value = value;
}
}

private Bitmap skyImage2Value;
public Bitmap SkyImage2
{
get
{
return skyImage2Value;
}

set
{
skyImage2Value = value;
}
}

private Bitmap skyImage3Value;
public Bitmap SkyImage3
{
get
{
return skyImage3Value;
}

set
{
skyImage3Value = value;
}
}

private Bitmap skyImage4Value;
public Bitmap SkyImage4
{
get
{
return skyImage4Value;
}

set
{
skyImage4Value = value;
}
}

private Bitmap skyImage5Value;
public Bitmap SkyImage5
{
get
{
return skyImage5Value;
}

set
{
skyImage5Value = value;
}
}

private List<ForeCast> foreCast_list = new List<ForeCast>();
public List<ForeCast> ForeCast_list
{
get
{
return foreCast_list;
}

set
{
foreCast_list = value;
}
}
}


Now for the current day the following code is used to get the skycode and the image:


reader.MoveToAttribute("skycode");
int.TryParse(reader.Value, out SkyCode);
currentWeatherReport.SkyCode = SkyCode;
string fileName = skyImagesRelativeUrl + currentWeatherReport.SkyCode + ".gif";
currentWeatherReport.SkyImage = new Bitmap(fileName);


this stores the skycode and add the URL to the images folder to it so in the end it would say \images\12.gif and that would be used to get the image.

im now doing a forecast from 4 additional days and with the other attributes ive saved them as attribute1, attribute2..., not the best way i know but its the method ive done.

i now want to uses the same kind of code as above but instead of saving it as SkyImage i want it to be SkyImage1, SkyImage2......

dglienna
September 3rd, 2009, 09:20 PM
That isn't an example of a lot of IF statements. That's because you are using ELSE IF with each one. This groups them into one SELECT statement, and only one executes each time.

InsyteMedia
September 5th, 2009, 07:39 PM
so any ideas regarding my problem?