2013-11-29 262 views
1

我正在從天氣網站xml文件here收集XML數據。XML元素選擇

我創建了以下代碼,它查找'temp_c'的第一個實例並返回值。這是當前的溫度。

using (XmlReader reader = XmlReader.Create(new StringReader(weather))) 
    { 
     while (reader.Read()) 
     { 
     switch (reader.NodeType) 
      { 
       case XmlNodeType.Element: 
       if (reader.Name.Equals("temp_c")) 
       { 
        reader.Read(); 
        temp_c = reader.Value; 
       } 
       break; 
      } 
    } 
} 
return temp_c 

這將返回名爲「temp_c」,以所謂的「temp_c」字符串的XML文件中的第一個實例的值

我現在想要做的是使用元素稱爲XML文檔中「句點」,並找到句號爲「fcttext」的元素。當「時期= 0」時,意味着「今天」,1 =明天等;而且我在與該週期值關聯的「fcttext_metric」數據之後。

我一直在努力工作的例子和XML閱讀代碼,我已經發現到當前的代碼,我在這裏。任何人都可以請我指出正確的方向?

編輯

下面是XML文件的例子:

<forecast> 
    <forecastday> 
     <period>0</period> 
     <fcttext_metric>Sunny</fcttext_metric> 
    <forecastday> 
     <period>1</period> 
     <fcttext_metric>Cloudy</fcttext_metric> 
+0

你可以編輯你的問題,在你的問題中包含一個*小*相關的XML樣例嗎?如果由於某種原因該外部位置不可用,則您的問題變得非常難以理解,並且該內容也無法搜索到。謝謝。 –

+0

現在編輯包括在內。 –

+0

+1。完善。謝謝。 :-) –

回答

1

這結束了更多的煩人,我原先預期,但你可以使用創建的XML對象圖DataContractSerializer和一組與您正在閱讀的XML相匹配的類。

首先,創建具有適當DataContract屬性的類。

[DataContract(Name = "response", Namespace = "")] 
public class WeatherData 
{ 
    [DataMember(Name = "forecast")] 
    public Forecast Forecast { get; set; } 
} 

[DataContract(Name = "forecast", Namespace = "")] 
public class Forecast 
{ 
    [DataMember(Name = "txt_forecast")] 
    public TxtForecast TxtForecast { get; set; } 
} 

[DataContract(Name = "txt_forecast", Namespace = "")] 
public class TxtForecast 
{ 
    [DataMember(Name = "forecastdays")] 
    public ForecastDay[] ForecastDays { get; set; } 
} 

[DataContract(Name = "forecastday", Namespace = "")] 
public class ForecastDay 
{ 
    [DataMember(Name = "period", Order = 1)] 
    public int Period { get; set; } 

    public string FctText { get; set; } 

    [DataMember(Name = "fcttext", EmitDefaultValue = false, Order = 5)] 
    private CDataWrapper FctTextWrapper 
    { 
     get { return FctText; } 
     set { FctText = value; } 
    } 
} 

繼承人變得複雜。 fcttext元素是CDATA,DataContractSerializer默認不支持。

使用可在Using CDATA with WCF REST starter kits獲得的精彩答案,您將創建一個CDataWrapper類。我不會在這裏重複代碼(因爲這是毫無意義的),只需點擊鏈接即可。

你可以看到我已經使用了上面的CDataWrapper類來處理fcttext元素。

一旦你有了類結構設置,你可以使用下面的代碼來提取你之後的信息。你只是在這個時候導航對象圖,所以你可以使用你想要的任何C#(我已經使用了一個簡單的LINQ查詢來查找期間0併爲它打印出fcttext)。

var s = new DataContractSerializer(typeof(WeatherData)); 
var reader = XmlReader.Create("http://api.wunderground.com/api/74e1025b64f874f6/forecast/conditions/q/zmw:00000.1.94787.xml"); 
var o = (WeatherData)s.ReadObject(reader); 

var firstPeriod = o.Forecast.TxtForecast.ForecastDays.Where(a => a.Period == 0).Single(); 
Console.WriteLine(firstPeriod.FctText); 

您可以根據需要擴展這些類,使您可以訪問XML中的其他字段。只要DataMember名稱匹配XML字段,它將全部工作。

這裏有一些問題,我跑進興趣的人的簡短摘要:

  • 我不得不將所有的類空字符串的命名空間屬性,因爲XML沒有任何名稱空間信息。
  • 訂單屬性在ForecastDay類中很重要。如果它們被忽略,DataContractSerializer根本就不會讀取fcttext字段(因爲它認爲fcttext應該是第一個?不知道爲什麼要誠實)。