如何按相反的日期顺序对数据列表进行排序?

How do I sort the list of data in reverse date order?

提问人:Andrew Truckle 提问时间:9/8/2023 最后编辑:Andrew Truckle 更新时间:9/8/2023 访问量:59

问:

示例 XML:

<AssignmentHistory>
    <PublicTalkInfo>
        <PublicTalkNumber>21</PublicTalkNumber>
        <PublicTalkSpeaker>Name3</PublicTalkSpeaker>
        <PublicTalkCongregation>Place3</PublicTalkCongregation>
    </PublicTalkInfo>
    <PublicTalkInfo>
        <MeetingDate>2023-10-15</MeetingDate>
        <PublicTalkNumber>21</PublicTalkNumber>
        <PublicTalkSpeaker>Name</PublicTalkSpeaker>
        <PublicTalkCongregation>Place</PublicTalkCongregation>
    </PublicTalkInfo>
    <PublicTalkInfo>
        <MeetingDate>2023-11-15</MeetingDate>
        <PublicTalkNumber>21</PublicTalkNumber>
        <PublicTalkSpeaker>Name2 </PublicTalkSpeaker>
        <PublicTalkCongregation>Place</PublicTalkCongregation>
    </PublicTalkInfo>
</AssignmentHistory>

为了简化,我把它剪掉了。

public string[] GetHistoryForTalkOutline(string historyDatabase, int talknumber)
{
    List<string> list = new List<string>();
    try
    {
        XDocument doc = XDocument.Load(historyDatabase);
        var ptInfo = doc
                        .Descendants("PublicTalkInfo")
                        .Where(p => p.Element("PublicTalkNumber").Value == talknumber.ToString()).ToList();
        SimpleLog.Log(ptInfo.Count().ToString());
           foreach (var pt in ptInfo)
           {
               var date = pt.Element("MeetingDate");
               var speaker = pt.Element("PublicTalkSpeaker");
               var cong = pt.Element("PublicTalkCongregation");

               if (date != null && speaker != null && cong != null)
               {
                   DateTime objectdate = DateTime.Parse(date.Value);
                   string histitem = objectdate.ToString("d") + ", ";
                   histitem += speaker.Value + " (";
                   histitem += cong.Value + ")";
                   list.Add(histitem);
               }

           }

        return list.ToArray();
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
        return null;
    }
}

我相信代码可以简化。但是,我怎样才能用降序的日期顺序构建我的最终字符串列表呢?请注意,某些条目中没有字段。

C# LINQ-to-XML

评论

1赞 DavidG 9/8/2023
请确保您提供有效的 XML。这里的 XML 没有根元素,结束标记也不都匹配,因此甚至无法解析
0赞 Andrew Truckle 9/8/2023
@DavidG我改进了它,谢谢。

答:

1赞 DavidG 9/8/2023 #1

与其将所有值存储在字符串列表中,不如以保留日期值的格式保存它们。例如,使用元组

List<(DateTime Date, string Value)> list = new List<(DateTime, string)>();

稍后,当您添加到列表中时,请执行以下操作:

list.Add((objectdate, histitem));

若要按所需顺序返回值,请使用一些简单的 Linq:

return list
    .OrderByDescending(x => x.Date)
    .Select(x => x.Value)
    .ToArray();

评论

0赞 Andrew Truckle 9/8/2023
我喜欢这种方法,因为它仅限于感兴趣的数据。
0赞 Andrew O. 9/8/2023 #2

也许可以尝试以下几点

using System.Xml.Linq;

....
        var doc = XDocument.Parse(xml);
        
        var emptyDate = DateTime.MinValue;
        var sortedElements = doc.Root.Elements("PublicTalkInfo")
            .OrderByDescending(e => e.Element("MeetingDate") != null 
                ? (DateTime)e.Element("MeetingDate") 
                : emptyDate)
            .ToList();

如果您希望没有会议日期的元素显示在列表顶部,则可以将DateTime.MinValue -> DateTime.MaxValue

评论

1赞 DavidG 9/8/2023
当缺少元素时,这将引发异常MeetingDate
1赞 Andrew O. 9/8/2023
你是对的,在上面的代码中更正了它。
0赞 Lins 9/8/2023 #3

也许,这样的事情应该会有所帮助::

using System.Xml.Linq;
XElement root = XElement.Load("file.xml");
var orderedtabs = root.Elements("PublicTalkInfo")
                    .OrderBy(xtab => (DateTime?)xtab.Element("MeetingDate"))
                    .ToArray();
root.RemoveAll();
foreach(XElement tab in orderedtabs)
    root.Add(tab);
root.Save("file-sorted.xml");