Reputation: 71
I am working on a project that calls an API (using C# ASP.NET), and the API returns an XML document. I know how to deserialize an response in JSON, but am running into issues with deserializing an XML response. Currently I am getting the below error when attempting to deserialize the XML:
InvalidOperationException: response xmlns="" was not expected.
The error code displayed just the empty quotes in the error message. I have the code samples below, and I would greatly appreciate any constructive feedback or advice on making this better, and any advice on where I went wrong on attempting to deserialize this!
Here is the XML response from the API call (This API only returns either CML or a .csv):
<response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:noNamespaceSchemaLocation="http://www.aviationweather.gov/static/adds/schema/metar1_2.xsd">
<request_index>554967903</request_index>
<data_source name="metars"/>
<request type="retrieve"/>
<errors/>
<warnings/>
<time_taken_ms>7</time_taken_ms>
<data num_results="3">
<METAR>
<raw_text>KDEN 102353Z 15007KT 10SM FEW220 07/M08 A3038 RMK AO2 SLP285 T00721083 10133 20072 58015</raw_text>
<station_id>KDEN</station_id>
<observation_time>2022-01-10T23:53:00Z</observation_time>
<latitude>39.85</latitude>
<longitude>-104.65</longitude>
<temp_c>7.2</temp_c>
<dewpoint_c>-8.3</dewpoint_c>
<wind_dir_degrees>150</wind_dir_degrees>
<wind_speed_kt>7</wind_speed_kt>
<visibility_statute_mi>10.0</visibility_statute_mi>
<altim_in_hg>30.380905</altim_in_hg>
<sea_level_pressure_mb>1028.5</sea_level_pressure_mb>
<quality_control_flags>
<auto_station>TRUE</auto_station>
</quality_control_flags>
<sky_condition sky_cover="FEW" cloud_base_ft_agl="22000"/>
<flight_category>VFR</flight_category>
<three_hr_pressure_tendency_mb>-1.5</three_hr_pressure_tendency_mb>
<maxT_c>13.3</maxT_c>
<minT_c>7.2</minT_c>
<metar_type>METAR</metar_type>
<elevation_m>1656.0</elevation_m>
</METAR>
<METAR>
<raw_text>KSEA 102353Z 34003KT 6SM -RA BR FEW015 BKN035 OVC045 08/06 A3035 RMK AO2 SLP288 P0000 60001 T00780056 10083 20044 50003</raw_text>
<station_id>KSEA</station_id>
<observation_time>2022-01-10T23:53:00Z</observation_time>
<latitude>47.45</latitude>
<longitude>-122.32</longitude>
<temp_c>7.8</temp_c>
<dewpoint_c>5.6</dewpoint_c>
<wind_dir_degrees>340</wind_dir_degrees>
<wind_speed_kt>3</wind_speed_kt>
<visibility_statute_mi>6.0</visibility_statute_mi>
<altim_in_hg>30.351377</altim_in_hg>
<sea_level_pressure_mb>1028.8</sea_level_pressure_mb>
<quality_control_flags>
<auto_station>TRUE</auto_station>
</quality_control_flags>
<wx_string>-RA BR</wx_string>
<sky_condition sky_cover="FEW" cloud_base_ft_agl="1500"/>
<sky_condition sky_cover="BKN" cloud_base_ft_agl="3500"/>
<sky_condition sky_cover="OVC" cloud_base_ft_agl="4500"/>
<flight_category>VFR</flight_category>
<three_hr_pressure_tendency_mb>0.3</three_hr_pressure_tendency_mb>
<maxT_c>8.3</maxT_c>
<minT_c>4.4</minT_c>
<precip_in>0.005</precip_in>
<pcp6hr_in>0.01</pcp6hr_in>
<metar_type>METAR</metar_type>
<elevation_m>115.0</elevation_m>
</METAR>
<METAR>
<raw_text>PHNL 102353Z 19009KT 10SM FEW025 FEW035 SCT050 26/21 A2997 RMK AO2 SLP147 T02560206 10261 20200 58017</raw_text>
<station_id>PHNL</station_id>
<observation_time>2022-01-10T23:53:00Z</observation_time>
<latitude>21.33</latitude>
<longitude>-157.93</longitude>
<temp_c>25.6</temp_c>
<dewpoint_c>20.6</dewpoint_c>
<wind_dir_degrees>190</wind_dir_degrees>
<wind_speed_kt>9</wind_speed_kt>
<visibility_statute_mi>10.0</visibility_statute_mi>
<altim_in_hg>29.970472</altim_in_hg>
<sea_level_pressure_mb>1014.7</sea_level_pressure_mb>
<quality_control_flags>
<auto_station>TRUE</auto_station>
</quality_control_flags>
<sky_condition sky_cover="FEW" cloud_base_ft_agl="2500"/>
<sky_condition sky_cover="FEW" cloud_base_ft_agl="3500"/>
<sky_condition sky_cover="SCT" cloud_base_ft_agl="5000"/>
<flight_category>VFR</flight_category>
<three_hr_pressure_tendency_mb>-1.7</three_hr_pressure_tendency_mb>
<maxT_c>26.1</maxT_c>
<minT_c>20.0</minT_c>
<metar_type>METAR</metar_type>
<elevation_m>2.0</elevation_m>
</METAR>
</data>
</response>
This is the code to call the API:
private static readonly HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
client.DefaultRequestHeaders.Accept.Clear();
string baseUrl = "https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&stationString=KMSP&hoursBeforeNow=2";
client.BaseAddress = new Uri(baseUrl);
HttpResponseMessage result = client.GetAsync(baseUrl).Result;
XmlSerializer serialObject = new XmlSerializer(typeof(MetarReport));
List<MetarReport> MetarCollection = new List<MetarReport>();
if (result.IsSuccessStatusCode)
{
using (Stream reader = result.Content.ReadAsStreamAsync().Result)
{
MetarReport metar = new MetarReport();
metar = (MetarReport)serialObject.Deserialize(reader);
MetarCollection.Add(metar);
}
}
// Test deserializer
foreach(var item in MetarCollection)
{
Console.WriteLine(item.rawText);
}
Console.ReadLine();
}
And this is the object I am attempting to deserialize the XML into
[XmlRoot("METAR")]
[XmlType("METAR")]
public class MetarReport
{
[XmlElement("raw_text")]
public string rawText { get; set; }
[XmlElement("station_id")]
public string stationId { get; set; }
[XmlElement("latitude")]
public double latitiude { get; set; }
[XmlElement("longitude")]
public double longitude { get; set; }
[XmlElement("temp_c")]
public double tempCelsius { get; set; }
[XmlElement("dewpoint_c")]
public double dewpoint { get; set; }
[XmlElement("wind_dir_degree")]
public int windDirection { get; set; }
[XmlElement("wind_speed_kt")]
public double windspeed { get; set; }
[XmlElement("visibility_statute_mi")]
public double visbilityMiles { get; set; }
[XmlElement("altim_in_hg")]
public double altimeter { get; set; }
//[XmlElement("sky_condition")]
//public List<SkyCondition> skyConditions {get; set;}
[XmlElement("flight_category")]
public string flightCategory { get; set; }
[XmlElement("metar_type")]
public string metarType { get; set; }
[XmlElement("elevation_m")]
public double elevationMeters { get; set; }
}
Upvotes: 3
Views: 7961
Reputation: 43959
try this, it was tested in Visual Studio
HttpResponseMessage response= client.GetAsync(baseUrl).Result;
string xml;
if (response.IsSuccessStatusCode)
{
xml = response.Content.ReadAsStringAsync().Result;
}
Response result;
XmlSerializer serializer = new XmlSerializer(typeof(Response));
using (StringReader reader = new StringReader(xml))
{
result = (Response)serializer.Deserialize(reader);
}
classes
[XmlRoot(ElementName = "response")]
public class Response
{
[XmlElement(ElementName = "request_index")]
public int RequestIndex { get; set; }
[XmlElement(ElementName = "data_source")]
public DataSource DataSource { get; set; }
[XmlElement(ElementName = "request")]
public Request Request { get; set; }
[XmlElement(ElementName = "errors")]
public object Errors { get; set; }
[XmlElement(ElementName = "warnings")]
public object Warnings { get; set; }
[XmlElement(ElementName = "time_taken_ms")]
public int TimeTakenMs { get; set; }
[XmlElement(ElementName = "data")]
public Data Data { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation")]
public string NoNamespaceSchemaLocation { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "quality_control_flags")]
public class QualityControlFlags
{
[XmlElement(ElementName = "auto_station")]
public string AutoStation { get; set; }
}
[XmlRoot(ElementName = "sky_condition")]
public class SkyCondition
{
[XmlAttribute(AttributeName = "sky_cover")]
public string SkyCover { get; set; }
[XmlAttribute(AttributeName = "cloud_base_ft_agl")]
public int CloudBaseFtAgl { get; set; }
}
[XmlRoot(ElementName = "METAR")]
public class METAR
{
[XmlElement(ElementName = "sky_condition")]
public List<SkyCondition> SkyCondition { get; set; }
[XmlElement(ElementName = "flight_category")]
public string FlightCategory { get; set; }
[XmlElement(ElementName = "three_hr_pressure_tendency_mb")]
public double ThreeHrPressureTendencyMb { get; set; }
[XmlElement(ElementName = "maxT_c")]
public decimal MaxTC { get; set; }
[XmlElement(ElementName = "minT_c")]
public decimal MinTC { get; set; }
[XmlElement(ElementName = "precip_in")]
public double PrecipIn { get; set; }
[XmlElement(ElementName = "pcp6hr_in")]
public double Pcp6hrIn { get; set; }
[XmlElement(ElementName = "metar_type")]
public string MetarType { get; set; }
[XmlElement(ElementName = "elevation_m")]
public double ElevationM { get; set; }
[XmlElement(ElementName = "raw_text")]
public string RawText { get; set; }
[XmlElement(ElementName = "station_id")]
public string StationId { get; set; }
[XmlElement(ElementName = "observation_time")]
public DateTime ObservationTime { get; set; }
[XmlElement(ElementName = "latitude")]
public double Latitude { get; set; }
[XmlElement(ElementName = "longitude")]
public double Longitude { get; set; }
[XmlElement(ElementName = "temp_c")]
public double TempC { get; set; }
[XmlElement(ElementName = "dewpoint_c")]
public double DewpointC { get; set; }
[XmlElement(ElementName = "wind_dir_degrees")]
public int WindDirDegrees { get; set; }
[XmlElement(ElementName = "wind_speed_kt")]
public int WindSpeedKt { get; set; }
[XmlElement(ElementName = "visibility_statute_mi")]
public double VisibilityStatuteMi { get; set; }
[XmlElement(ElementName = "altim_in_hg")]
public double AltimInHg { get; set; }
[XmlElement(ElementName = "sea_level_pressure_mb")]
public decimal SeaLevelPressureMb { get; set; }
[XmlElement(ElementName = "quality_control_flags")]
public QualityControlFlags QualityControlFlags { get; set; }
}
[XmlRoot(ElementName = "data")]
public class Data
{
[XmlElement(ElementName = "METAR")]
public List<METAR> METAR { get; set; }
[XmlAttribute(AttributeName = "num_results")]
public int NumResults { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "data_source")]
public class DataSource
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "request")]
public class Request
{
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
}
Upvotes: 4