Как бы я использовал LINQ2XML в этом сценарии? - PullRequest
2 голосов
/ 12 февраля 2009

Мой запрос LINQ2XML работает на полпути к моей цели:

var XMLDoc = XDocument.Load("WeatherData.xml");

var maximums = from tempvalue in 
                   XMLDoc.Descendants("temperature").Elements("value")
               where tempvalue.Parent.Attribute("type").Value == "maximum"
               select (string)tempvalue;

var minimums = from tempvalue in 
                   XMLDoc.Descendants("temperature").Elements("value")
               where tempvalue.Parent.Attribute("type").Value == "minimum"
               select (string)tempvalue;

List<string> MaxTemps = maximums.ToList();
List<string> MinTemps = minimums.ToList();

Однако у меня возникают проблемы с получением информации о времени из XML-документа, потому что я должен сопоставить информацию о ключе макета (см. Комментарии XML), и мне интересно, что было бы лучшим решением в LINQ чтобы объединить данные этого времени с моими существующими запросами:

(Кстати, эти данные XML поступают из веб-службы)

<?xml version="1.0" encoding="utf-8"?>
<dwml>
  <data>
    <time-layout>
      <!--        Maximums Key         -->
      <layout-key>k-p24h-n7-1</layout-key>
      <start-valid-time>2009-02-09T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-09T19:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-10T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-10T19:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-11T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-11T19:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-12T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-12T19:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-13T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-13T19:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-14T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-14T19:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-15T07:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-15T19:00:00-05:00</end-valid-time>
    </time-layout>
    <time-layout>
      <!--        Minimums Key         -->
      <layout-key>k-p24h-n7-2</layout-key>
      <start-valid-time>2009-02-08T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-09T08:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-09T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-10T08:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-10T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-11T08:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-11T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-12T08:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-12T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-13T08:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-13T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-14T08:00:00-05:00</end-valid-time>
      <start-valid-time>2009-02-14T19:00:00-05:00</start-valid-time>
      <end-valid-time>2009-02-15T08:00:00-05:00</end-valid-time>
    </time-layout>
    <parameters>
      <!--                                     1st Key   -->
      <temperature type="maximum" time-layout="k-p24h-n7-1">
        <value>44</value>
        <value>57</value>
        <value>55</value>
        <value>40</value>
        <value>39</value>
        <value>34</value>
        <value>33</value>
      </temperature>
      <!--                                     2nd Key   -->
      <temperature type="minimum" time-layout="k-p24h-n7-2">
        <value>24</value>
        <value>38</value>
        <value>46</value>
        <value>35</value>
        <value>25</value>
        <value>27</value>
        <value>23</value>
      </temperature>
    </parameters>
  </data>
</dwml>

1 Ответ

6 голосов
/ 12 февраля 2009

Я бы начал с того, что разбил бы это на более мелкие кусочки. Во-первых, я бы преобразовал временные макеты в более работоспособную форму, сгруппированную по ключу макета, с действительными временем начала и допустимым временем окончания, связанными друг с другом:

var timeLayouts =
    from tempvalue in XMLDoc.Descendants("time-layout")
    let tempStartTimes = tempvalue.Elements("start-valid-time").
            Select((x, i) => new { Index = i, ValidDateTime = (DateTime)x })
    let tempEndTimes = tempvalue.Elements("end-valid-time").
            Select((x, i) => new { Index = i, ValidDateTime = (DateTime)x })
    select new
    {
        LayoutKey = tempvalue.Element("layout-key").Value,
        ValidTimeRanges =
            from s in tempStartTimes
            from e in tempEndTimes
            where s.Index == e.Index
            select new 
            { 
                Index = s.Index, 
                ValidStartDateTime = s.ValidDateTime, 
                ValidEndDateTime = e.ValidDateTime 
            }
    };

Тогда я бы массировал параметры примерно таким же образом:

var parameters =
    from tempvalue in XMLDoc.Descendants("temperature")
    select new
    {
        TemperatureType = (string) tempvalue.Attribute("type"),
        TimeLayout = (string) tempvalue.Attribute("time-layout"),
        Temperatures = tempvalue.Elements("value").Select((x, i) =>
            new { Index = i, Temperature = (int)x })
    };

Оттуда не так сложно получить максимумы и минимумы:

var maximums =
    from p in parameters
    where p.TemperatureType == "maximum"
    from tl in timeLayouts
    where tl.LayoutKey == p.TimeLayout
    from tr in tl.ValidTimeRanges
    from t in p.Temperatures
    where tr.Index == t.Index
    select new { tr.ValidStartDateTime, tr.ValidEndDateTime, 
        t.Temperature };

var minimums =
    from p in parameters
    where p.TemperatureType == "minimum"
    from tl in timeLayouts
    where tl.LayoutKey == p.TimeLayout
    from tr in tl.ValidTimeRanges
    from t in p.Temperatures
    where tr.Index == t.Index
    select new { tr.ValidStartDateTime, tr.ValidEndDateTime, 
        t.Temperature };

Вы могли бы пойти другим путем с этим, если вы хотите упростить некоторые представления (например, вы можете упростить макеты и параметры в нечто более «табличное»), для этого потребуется всего несколько настроек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...