简体   繁体   中英

need help using LINQ:XML to create an instance of a class

I have a class which defines meteorological measurements with an API. I have created classes to store these measurements within an XML file. I have been able to write to the XML file, but am unable to read from it. I need to be able to read the data, then instantiate the Measurement Class via the constructor, and then add these instances to a List Here is the code for the Measurement constructor

  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;
    }

and here is a sample of the XML file

<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>

And here is the method I have written to read the file, and make an instance of the class Measurement. I receive no errors, however have not managed to create the List<>

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()

I've also written another method, of a slightly different format..

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;
    }

Apologies if these questions seem silly, am VERY new to LINQ and XML, so finding my way very slowly..any help much appreciated! A console application calls this method for testing and produces nothing but WeatherAPI.Measurement WeatherAPI.Measurement

Help? thanks!

Overall, your code looks fine. As Jon Skeet pointed out in his comment, you don't need to bother adding each element to a list -- you can simply return the result of the query after calling .ToList() .

Most likely, there's either something wrong with your xml file, or you're reading it incorrectly.

If your xml file is truly just:

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

Then your code won't work, because the root of the xml file is Measurement . Therefore, calling doc.Root.Descendants("Measurement") will give you 0 results. Instead, your xml file should have a unique root element, for example:

<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>

Furthermore, you don't need to bother obtaining the Root of the xml document. If all you want to do is find elements named Measurement , just say doc.Descendants("Measurement") .

Try this code with the above xml file:

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; }
}

When I run it in LINQPad, I get the following result:

样本结果

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM