2013-10-11 4 views
0

Я использую API World Weather Online для получения погоды определенного местоположения. Моя проблема заключается в том, что я пытаюсь десериализовать вывод XML, поступающий из потока Response API, я получаю сообщение об ошибке: существует проблема с XML-документом (1,1).Невозможно десериализовать Xml от api

Uri apiURL = new Uri(@"http://api.worldweatheronline.com/free/v1/weather.ashx?q=Dhaka&format=xml&num_of_days=1&date=today&key=jzb88bpzb5yvaegukmq97mee"); 

    Stream result = RequestHandler.Process(apiURL.ToString()); 
    XmlSerializer des = new XmlSerializer(typeof(LocalWeather)); 
    StreamReader tr = new StreamReader(result); 
    Object obj = des.Deserialize(tr); 
    LocalWeather data = (LocalWeather)obj; 

Пример файла XML из Web API:

<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <request> 
     <type>City</type> 
     <query>Dhaka, Bangladesh</query> 
    </request> 
    <current_condition> 
     <observation_time>01:57 PM</observation_time> 
     <temp_C>33</temp_C> 
     <temp_F>91</temp_F> 
     <weatherCode>113</weatherCode> 
     <weatherIconUrl> 
      <![CDATA[http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0008_clear_sky_night.png]]> 
     </weatherIconUrl> 
     <weatherDesc> 
      <![CDATA[Clear ]]> 
     </weatherDesc> 
     <windspeedMiles>2</windspeedMiles> 
     <windspeedKmph>4</windspeedKmph> 
     <winddirDegree>77</winddirDegree> 
     <winddir16Point>ENE</winddir16Point> 
     <precipMM>0.0</precipMM> 
     <humidity>76</humidity> 
     <visibility>10</visibility> 
     <pressure>1006</pressure> 
     <cloudcover>2</cloudcover> 
    </current_condition> 
    <weather> 
     <date>2013-10-11</date> 
     <tempMaxC>36</tempMaxC> 
     <tempMaxF>97</tempMaxF> 
     <tempMinC>25</tempMinC> 
     <tempMinF>77</tempMinF> 
     <windspeedMiles>5</windspeedMiles> 
     <windspeedKmph>8</windspeedKmph> 
     <winddirection>ENE</winddirection> 
     <winddir16Point>ENE</winddir16Point> 
     <winddirDegree>65</winddirDegree> 
     <weatherCode>113</weatherCode> 
     <weatherIconUrl> 
      <![CDATA[http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0001_sunny.png]]> 
     </weatherIconUrl> 
     <weatherDesc> 
      <![CDATA[Sunny]]> 
     </weatherDesc> 
     <precipMM>0.0</precipMM> 
    </weather> 
</data> 

LocalWeather класс:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace APISample 
{ 
     public class LocalWeather 
     { 
      public Data data { get; set; } 
     } 

     public class Data 
     { 
      public List<Current_Condition> current_Condition { get; set; } 
      public List<Request> request { get; set; } 
      public List<Weather> weather { get; set; } 
     } 

     public class Current_Condition 
     { 
      public DateTime observation_time { get; set; } 
      public DateTime localObsDateTime { get; set; } 
      public int temp_C { get; set; } 
      public int windspeedMiles { get; set; } 
      public int windspeedKmph { get; set; } 
      public int winddirDegree { get; set; } 
      public string winddir16Point { get; set; } 
      public string weatherCode { get; set; } 
      public List<WeatherDesc> weatherDesc { get; set; } 
      public List<WeatherIconUrl> weatherIconUrl { get; set; } 
      public float precipMM { get; set; } 
      public float humidity { get; set; } 
      public int visibility { get; set; } 
      public int pressure { get; set; } 
      public int cloudcover { get; set; } 
     } 

     public class Request 
     { 
      public string query { get; set; } 
      public string type { get; set; } 
     } 

     public class Weather 
     { 
      public DateTime date { get; set; } 
      public int tempMaxC { get; set; } 
      public int tempMaxF { get; set; } 
      public int tempMinC { get; set; } 
      public int tempMinF { get; set; } 
      public int windspeedMiles { get; set; } 
      public int windspeedKmph { get; set; } 
      public int winddirDegree { get; set; } 
      public string winddir16Point { get; set; } 
      public string weatherCode { get; set; } 
      public List<WeatherDesc> weatherDesc { get; set; } 
      public List<WeatherIconUrl> weatherIconUrl { get; set; } 
      public float precipMM { get; set; } 
     } 

     public class WeatherDesc 
     { 
      public string value { get; set; } 
     } 

     public class WeatherIconUrl 
     { 
      public string value { get; set; } 
     } 
} 
+0

Может быть несколько причин, почему это не удается, скорее всего, ваша модель не совпадает с XML - проверить 'InnerException' для * реальный * выпуск. – James

+0

Как сказал Джеймс, дважды проверьте свой класс LocalWeather, чтобы убедиться, что ваша модель соответствует XML, который вы используете. Отправьте класс здесь, если вы хотите другой набор глаз. –

+0

@ DanielSimpkins: Я опубликовал класс LocalWeather. – jchoudhury

ответ

2

Вам нужно обновить класс, чтобы соответствовать схеме структуры XML (они чувствительны к регистру).

Вы можете начать с существующего файла, используя атрибуты, найденные в System.Xml.Serialization.

[XmlRoot("data")] 
public class Data { 
// and so on.. 
} 

Или вы можете использовать инструмент XSD для создания класса для вас, следуя этим шагам.

  1. Создать схему для возвращения XML из сервиса (Xml -> Создание схемы)
  2. В VS Studio Tools запустить эту команду: XSD XmlSchema.xsd/с (где XmlSchema.xsd это схема, полученный на стадии 1).
0

Способ, которым ваша модель настроена прямо сейчас, у вас есть LocalWeather как корень, тогда как в фактическом XML корень - это Data. Вот почему вы получаете ошибку «Недопустимый корневой узел». Таким образом, вместо

XmlSerializer des = new XmlSerializer(typeof(LocalWeather)); 
StreamReader tr = new StreamReader(result); 
Object obj = des.Deserialize(tr); 
LocalWeather data = (LocalWeather)obj; 

попробовать

XmlSerializer des = new XmlSerializer(typeof(Data)); 
StreamReader tr = new StreamReader(result); 
Object obj = des.Deserialize(tr); 
Data data = (Data)obj; 
Смежные вопросы