需要帮助使用LINQ:XML来创建类的实例

时间:2011-04-03 17:54:07

标签: c# linq-to-xml

我有一个用API定义气象测量的课程。我已经创建了将这些测量值存储在XML文件中的类。我已经能够写入XML文件,但无法从中读取。我需要能够读取数据,然后通过构造函数实例化Measurement Class,然后将这些实例添加到List中 以下是Measurement构造函数的代码

  public Measurement(string longit, string latitud, string cty, string pcode, DateTime dte, decimal huy, decimal pre, string windDir, int windSp) : base(longit, latitud, cty,pcode)
    {

        dte = date;
        huy = humidity;
        pre = precipitation;           
        windDir = windDirection;
        windSp = windSpeed;
    }

以下是XML文件的示例

<Measurement>
<longitude>-76.2858726</longitude>
<latitude>36.8507689</latitude>
<city>Thetford</city>
<postcode>IP24 1ED</postcode>
<date>01/04/2011</date>
<windDirection>SE</windDirection>
<windSpeed>8</windSpeed>
<humidity>2.6</humidity>
<precipitation>0.0</precipitation>
</Measurement>

这是我编写的用于读取文件的方法,并创建了类Measurement的实例。我没有收到任何错误,但是没有设法创建List&lt;&gt;

public List<Measurement> GetList()
    {
        List<Measurement> measurements = new List<Measurement>();
        XDocument doc = XDocument.Load(@"C:\Users\Sonya\Documents\Visual Studio 2010\Projects\WeatherAPI\WeatherAPI\measurement_store.xml");
        XElement root = doc.Root;

     var d = (from s in root.Descendants("Measurement")
                 select new Measurement
                 {
                     Longitude = s.Element("longitude").Value,
                     Latitude = s.Element("latitude").Value,
                     City = s.Element("city").Value,
                     Postcode = s.Element("postcode").Value,
                     Date = DateTime.Parse(s.Element("date").Value),
                     Humidity = decimal.Parse(s.Element("humidity").Value),
                     Precipitation = decimal.Parse(s.Element("precipitation").Value),
                     WindSpeed = Convert.ToInt32(s.Element("windSpeed").Value),
                     WindDirection = s.Element("windDirection").Value,

                 }).ToList();


     d.ForEach(measurements.Add);

        return measurements;
    }//end GetList()

我还写了另一种格式略有不同的方法..

public List<Measurement> createXMLListMeasurements()
    {
        //load the xml document
        XDocument doc = XDocument.Load(@"C:\Users\Sonya\Documents\Visual Studio 2010\Projects\WeatherAPI\WeatherAPI\measurement_store.xml");
        //XElement root = doc.Root;

        //instantiate a new list of measurements
        List<Measurement> measurements = new List<Measurement>();

            //get a list of measurement elements
           var d = from s in doc.Descendants("Measurement")
                    //where
                    select new 
                    { //assign Measurement variables to data from xml doc
                        Longitude = (string)s.Element("longitude").Value,
                        Latitude = (string)s.Element("latitude").Value,
                        City = (string)s.Element("city").Value,
                        Postcode = (string)s.Element("postcode").Value,
                        Date = DateTime.Parse(s.Element("date").Value),
                        Humidity = decimal.Parse(s.Element("humidity").Value),
                        Precipitation = decimal.Parse(s.Element("precipitation").Value),
                        WindSpeed = Convert.ToInt32(s.Element("windSpeed").Value),
                        WindDirection = (string)s.Element("windDirection").Value,
                    };

           foreach (var s in d)
           {   //for each element found, instantiate Measurements class, and add to the measurements list.
               Measurement m = new Measurement(s.Longitude, s.Latitude, s.City, s.Postcode, s.Date, s.Humidity, s.Precipitation, s.WindDirection, s.WindSpeed);
               measurements.Add(m);

           }


        return measurements;
    }

道歉,如果这些问题看起来很愚蠢,对LINQ和XML来说是非常新的,所以找到我的方式非常慢......非常感谢!控制台应用程序调用此方法进行测试,但只生成 WeatherAPI.Measurement WeatherAPI.Measurement

帮助?谢谢!

1 个答案:

答案 0 :(得分:1)

总的来说,您的代码看起来很好。正如Jon Skeet在他的评论中指出的那样,您不需要费心将每个元素添加到列表中 - 您只需在调用.ToList()后返回查询结果。

最有可能的是,你的xml文件有问题,或者你读错了。

如果您的xml文件真的只是:

<Measurement>
    <longitude>-76.2858726</longitude>
    <latitude>36.8507689</latitude>
    <city>Thetford</city>
</Measurement>

然后您的代码将无效,因为xml文件的 root 度量。因此,调用doc.Root.Descendants("Measurement")会得到0结果。相反,您的xml文件应具有唯一的根元素,例如:

<root>
    <Measurement>
        <longitude>-76.2858726</longitude>
        <latitude>36.8507689</latitude>
        <city>Thetford</city>
    </Measurement>
    <Measurement>
        <longitude>-71.2858726</longitude>
        <latitude>32.1507689</latitude>
        <city>Other City</city>
    </Measurement>
</root>

此外,您无需费心获取xml文档的Root。如果您只想找到名为Measurement的元素,只需说出doc.Descendants("Measurement")

使用上面的xml文件尝试此代码:

void Main()
{
    var measurements = GetMeasurements(@"C:\path\to\file\measurements.xml");
}

public List<Measurement> GetMeasurements(string path)
{
    XDocument doc = XDocument.Load(path);

    return (from s in doc.Descendants("Measurement")
            select new Measurement
            {
                 Longitude = Convert.ToDecimal(s.Element("longitude").Value),
                 Latitude = Convert.ToDecimal(s.Element("latitude").Value),
                 City = s.Element("city").Value,
            }).ToList();
}

public class Measurement
{
    public decimal Longitude { get; set; }
    public decimal Latitude { get; set; }
    public string City { get; set; }
}

当我在LINQPad中运行它时,我得到以下结果:

sample result