Reputation: 1859
I have my LINQ2XML query working half way to my goal:
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();
However, I'm having trouble with getting the time information from the XML document, because I have to match the layout-key information(see the XML comments), and I'm wondering what would be the best solution in LINQ to join this time data with my existing queries:
(By the way, this XML data comes from a web service)
<?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>
Upvotes: 2
Views: 3220
Reputation: 74560
I would start out by breaking this down into smaller pieces. First, I would massage the time layouts into a more workable form, grouped by the layout key, with the valid start time and valid end time associated with each other:
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
}
};
Then, I would massage the parameters in much the same way:
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 })
};
From there, it's not so hard to get your maximums and minimums:
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 };
You could go some other ways with this, if you wanted to simplify some of the representations (you could flatten out the layouts and parameters into something more "tabular", for example), it would just require a few tweaks.
Upvotes: 6