【问题标题】:How would I use LINQ2XML in this scenario?在这种情况下我将如何使用 LINQ2XML?
【发布时间】:2009-02-12 17:26:53
【问题描述】:

我的 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 cmets),我想知道 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>

【问题讨论】:

    标签: c# .net xml linq linq-to-xml


    【解决方案1】:

    我会先把它分解成更小的部分。首先,我会将时间布局转化为更可行的形式,按布局键分组,有效开始时间和有效结束时间相互关联:

    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 };
    

    如果您想简化一些表示形式(例如,您可以将布局和参数扁平化为更“表格”的东西),您可以采用其他方式,它只需要一些调整。

    【讨论】:

    • 非常感谢!我一直在努力解决这个问题,阅读书籍,代码示例等,但没有什么适合我的场景。您的 timeLayouts 查询对我几乎整个 SOAP 服务都很有用。
    • @M4dRefluX:没问题。如果您对具体细节有任何疑问,请随时提问。
    猜你喜欢
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2015-11-30
    • 2017-05-16
    相关资源
    最近更新 更多