XML元素选择

时间:2013-11-29 00:45:32

标签: c# xml

我正在从天气网站xml文件here收集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”的XML文件中的第一个实例的值返回给名为“temp_c”的字符串

我现在要做的是使用名为“period”的XML文档中的Element和名为“fcttext”的句点找到的元素。当“period = 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>

1 个答案:

答案 0 :(得分:1)

这最终让我觉得更烦人,但您可以使用DataContractSerializer和一组与您正在阅读的XML相匹配的类从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查询来查找Period 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字段匹配,它就会起作用。

以下是我遇到的一些问题的简短摘要:

  • 我必须将所有类的Namespace属性设置为空字符串,因为XML中没有任何命名空间信息。
  • 订单属性在ForecastDay类中很重要。如果它们被省略,DataContractSerializer最终根本没有读取fcttext字段(因为它认为fcttext应该先出现?不确定为什么说实话)。