我有一个用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
帮助?谢谢!
答案 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中运行它时,我得到以下结果: