2014-03-06 3 views
0

linq to xml을 사용하여 xmlstring xmlData에서 Station 데이터 목록을 추출합니다. XMLDATA는 다음과 같습니다 : 나는 가장 최근의 날짜에 대한 역의 이름을 추출하기 위해이 xmlString을을 조회하려고where 절을 사용하여 XML을 쿼리하는 방법은 무엇입니까?

<Observations> 
    <Observation> 
    <Station>ADELONG POST OFFICE</Station> 
    <DateTime>2010-09-02T00:00:00</DateTime> 
    <Temperature>19.212989033764689</Temperature> 
    </Observation> 
<Observation> 
    <Station>ADELONG POST OFFICE</Station> 
    <DateTime>2010-09-01T00:00:00</DateTime> 
    <Temperature>28.529448969536205</Temperature> 
    </Observation> 
    <Observation> 
    <Station>ALBURY AIRPORT</Station> 
    <DateTime>2010-09-01T00:00:00</DateTime> 
    <Temperature>34.687027630716109</Temperature> 
    </Observation> 
    <Observation> 
    <Station>ALBURY AIRPORT AWS</Station> 
    <DateTime>2010-09-01T00:00:00</DateTime> 
    <Temperature>28.131385570453197</Temperature> 
    </Observation> 
</Observations> 

. 나는 또한 가장 최근 온도를 검색하고 싶습니다.

public class Station 
{ 
    public string Name { get; set; } 
    public DateTime MostRecentDate { get; set; } 
    public decimal LastTemperature { get; set; } 
} 

가 어떻게 각 스테이션에 대한 가장 최근의 온도 + 날짜 + 이름을 나열 할 수 있습니다

나는 스테이션 클래스를 정의?

나는이 교류에서 # 콘솔 응용 프로그램을 실행하고 (전체 코드) : 여기

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Xml; 
using System.Xml.Linq; 

namespace weatherxml 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string xmlData = @"<Observations><Observation><Station>ADELONG POST OFFICE</Station><DateTime>2010-09-02T00:00:00</DateTime><Temperature>19.212989033764689</Temperature></Observation><Observation><Station>ADELONG POST OFFICE</Station><DateTime>2010-09-01T00:00:00</DateTime><Temperature>28.529448969536205</Temperature></Observation><Observation><Station>ALBURY AIRPORT</Station><DateTime>2010-09-01T00:00:00</DateTime><Temperature>34.687027630716109</Temperature></Observation><Observation><Station>ALBURY AIRPORT AWS</Station><DateTime>2010-09-01T00:00:00</DateTime><Temperature>28.131385570453197</Temperature></Observation></Observations>"; 
      XDocument weatherData = XDocument.Parse(xmlData); 

      var stations = from item in weatherData.Descendants("Observation") 
          select new Station 
          { 
           Name = item.Element("Station").Value, 
           MostRecentDate = DateTime.Parse(item.Element("DateTime").Value), 
           LastTemperature = Decimal.Parse(item.Element("Temperature").Value) 

          }; 

      var st = stations; 

      foreach (var s in st) 
      { 
       Console.WriteLine(s.Name); 
      } 
      Console.ReadLine(); 
     } 
    } 

    public class Station 
    { 
     public string Name { get; set; } 
     public DateTime MostRecentDate { get; set; } 
     public decimal LastTemperature { get; set; } 

    } 
} 

답변

0

각 그룹에서 관찰 가진 최대 날짜를 선택, 역 이름으로 그룹에 데이터를보십시오.

var stations = from item in weatherData.Descendants("Observation") 
       group item by (string) item.Element("Station") 
       into g 
       let date = g.Max(o => DateTime.Parse((string)o.Element("DateTime"))) 
       select new 
       { 
        Name = g.Key, 
        MostRecentDate = date, 
        LastTemperature = Decimal.Parse((string)g.FirstOrDefault(o => date == DateTime.Parse((string)o.Element("DateTime"))).Element("Temperature")) 
       }; 

을하지만이 방법은 더 읽을 :이 LINQ 쿼리 작업을해야합니다

var query = from item in weatherData.Descendants("Observation") 
      group item by (string) item.Element("Station") 
      into g 
      select g; 
var stations = new List<Station>(); 
foreach (var q in query) 
{ 
    //maximum date in current group 
    var maxDate = q.Max(o => DateTime.Parse((string) o.Element("DateTime"))); 
    //1st observation having date equal maximum date 
    var latestObservation = q.FirstOrDefault(o => DateTime.Parse((string) o.Element("DateTime")) == maxDate); 

    //create new Station using data from latest observation 
    var newStation = new Station(); 
    newStation.Name = q.Key; 
    newStation.MostRecentDate = maxDate; 
    newStation.LastTemperature = Decimal.Parse((string)latestObservation.Element("Temperature")); 

    //add newly created Station to result list 
    stations.Add(newStation); 
} 
0

는 유사한 코드가 있어야

이 귀하의 요구 사항으로 변환 당신과 비슷한 또 다른 StackOverflow의 질문에 Link있어 이 :

var op = from station in stations 
       group station by station.Name into grp 
       let recentTimestamp = grp.OrderByDescending(t => t.MostRecentDate).FirstOrDefault() 
       select recentTimestamp; 

제 2의 LINQ 쿼리를 사용하지 않고도 제거 할 수 있습니다. 당신은 오직 최근 항목 만 골라야합니다.

0

사용 GROUPBY 절

var에 일 = 방송국의에서 그룹의 s.Name에 의한 결과로 새로운 {역 = result.Key을 선택 , MostRecent = result.Max (항목 => item.MostRecentDate) };

  foreach (var s in st) 
      { 
       Console.WriteLine(s.MostRecent); 
       Console.WriteLine(s.Station); 
      } 
0
using System; 
using System.Collections.Generic; 
using System.Data; 
using System.IO; 
using System.Linq; 

namespace weatherxml 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string xmlData = @"<Observations><Observation><Station>ADELONG POST OFFICE</Station><DateTime>2010-09-02T00:00:00</DateTime><Temperature>19.212989033764689</Temperature></Observation><Observation><Station>ADELONG POST OFFICE</Station><DateTime>2010-09-01T00:00:00</DateTime><Temperature>28.529448969536205</Temperature></Observation><Observation><Station>ALBURY AIRPORT</Station><DateTime>2010-09-01T00:00:00</DateTime><Temperature>34.687027630716109</Temperature></Observation><Observation><Station>ALBURY AIRPORT AWS</Station><DateTime>2010-09-01T00:00:00</DateTime><Temperature>28.131385570453197</Temperature></Observation></Observations>"; 
      var stl = new List<Station>(); 
      using (DataSet ds = new DataSet()) 
      { 
       ds.ReadXml(new StringReader(xmlData)); 

       //i want proper types, not strings 
       DataColumn dc = ds.Tables[0].Columns.Add("dt", typeof(DateTime)); 
       dc.Expression = "DateTime"; 
       dc = ds.Tables[0].Columns.Add("temp", typeof(Decimal)); 
       dc.Expression = "Temperature"; 

       //group by 
       var result = ds.Tables[0].AsEnumerable().GroupBy(a => a.Field<string>("Station")).Select(g => g.OrderByDescending(a => a.Field<DateTime>("dt"))); 

       //create result 
       foreach(var i in result) 
       { 
        var fi = i.First(); 
        stl.Add(new Station() { Name = fi.Field<string>("Station"), LastTemperature = fi.Field<decimal>("temp"), MostRecentDate = fi.Field<DateTime>("dt") }); 
       } 
       //here the stationList (stl) has info for all stations 
      } 
      Console.ReadLine(); 
     } 
    } 

    public class Station 
    { 
     public string Name { get; set; } 
     public DateTime MostRecentDate { get; set; } 
     public decimal LastTemperature { get; set; } 

    } 
} 
관련 문제