Я бы начал с того, что разбил бы это на более мелкие кусочки. Во-первых, я бы преобразовал временные макеты в более работоспособную форму, сгруппированную по ключу макета, с действительными временем начала и допустимым временем окончания, связанными друг с другом:
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 };
Вы могли бы пойти другим путем с этим, если вы хотите упростить некоторые представления (например, вы можете упростить макеты и параметры в нечто более «табличное»), для этого потребуется всего несколько настроек.