Search code examples
c#linq-to-xml

Can this code snippet be moved into the other code block?


Given this code:

public WeekendMeetingHistoryItem[] ExtractFutureWeekendMeetingHistoryItems(DateTime datWeekOfMeeting, String strHistoryDatabase)
{
    List<WeekendMeetingHistoryItem> listHistoryItems = new List<WeekendMeetingHistoryItem>();

    try
    {
        // Read the XML file
        XDocument docAssignHistory = XDocument.Load(strHistoryDatabase);

        var listHistory = docAssignHistory.Descendants("PublicTalkInfo")
                            .Where(x => ConvertWeekNameToDate(x.Parent.Name.ToString()) > datWeekOfMeeting);
        foreach (XElement nodeHistoryItem in listHistory)
        {
            DateTime datHistoryItemWeekOfMeeting = ConvertWeekNameToDate(nodeHistoryItem.Parent.Name.ToString());
            WeekendMeetingHistoryItem oItem = new WeekendMeetingHistoryItem
            {
                Week = datHistoryItemWeekOfMeeting,
                Chairman = nodeHistoryItem.Element("PublicTalkChairman")?.Value,
                OpeningPrayer = nodeHistoryItem.Element("PrayerOpen")?.Value,
                ConcludingPrayer = nodeHistoryItem.Element("PrayerClose")?.Value,
                Host = nodeHistoryItem.Element("VideoConferenceHost")?.Value,
                Cohost = nodeHistoryItem.Element("VideoConferenceCohost")?.Value,
                HomeSpeaker = nodeHistoryItem.Element("PublicTalkSpeaker")?.Value,
                Interpreter = nodeHistoryItem.Element("Interpreter")?.Value,
                Hospitality = nodeHistoryItem.Element("PublicTalkHospitality")?.Value,
                AwaySpeaker1 = nodeHistoryItem.Element("AwaySpeaker1")?.Value,
                AwaySpeaker2 = nodeHistoryItem.Element("AwaySpeaker2")?.Value,
                WatchtowerConductor = nodeHistoryItem.Element("WatchtowerConductor")?.Value,
                WatchtowerReader = nodeHistoryItem.Element("WatchtowerReader")?.Value,
                WatchtowerBibleVersesReader = nodeHistoryItem.Element("BibleVersesReader")?.Value,
                Miscellaneous = nodeHistoryItem.Element("Misc")?.Value
            };

            var awayTalks = nodeHistoryItem.Element("AwayTalks");
            if (awayTalks != null)
            {
                var awayTalkList = awayTalks.Descendants("AwayTalk");
                if (awayTalkList != null)
                {
                    foreach (var awayTalkItem in awayTalkList)
                    {
                        AwayTalk item = new AwayTalk
                        {
                            Speaker = awayTalkItem.Element("Speaker").Value,
                            Congregation = awayTalkItem.Element("Congregation").Value,
                            TalkNumber = awayTalkItem.Element("TalkNumber").Value,
                            MeetingDate = DateTime.Parse(awayTalkItem.Element("MeetingDate").Value)
                        };
                        oItem.AwayTalks.Add(item);
                    }
                }
            }

            listHistoryItems.Add(oItem);
        }
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
        return null; 
    }

    return listHistoryItems.ToArray();
}

Is it possible to move this bit:

var awayTalks = nodeHistoryItem.Element("AwayTalks");
if (awayTalks != null)
{
    var awayTalkList = awayTalks.Descendants("AwayTalk");
    if (awayTalkList != null)
    {
        foreach (var awayTalkItem in awayTalkList)
        {
            AwayTalk item = new AwayTalk
            {
                Speaker = awayTalkItem.Element("Speaker").Value,
                Congregation = awayTalkItem.Element("Congregation").Value,
                TalkNumber = awayTalkItem.Element("TalkNumber").Value,
                MeetingDate = DateTime.Parse(awayTalkItem.Element("MeetingDate").Value)
            };
            oItem.AwayTalks.Add(item);
        }
    }
}

Can it be moved up into this code block:

WeekendMeetingHistoryItem oItem = new WeekendMeetingHistoryItem
{
    // ...
}

Solution

  • Yes it can be done, with using Linq lambda syntax like the below :

    
    var oItem = new WeekendMeetingHistoryItem
    {
        AwayTalks = nodeHistoryItem.Element("AwayTalks")?.Descendants("AwayTalk")
                    .Select(r=>  new AwayTalk {
                      Speaker = r.Element("Speaker").Value,
                      Congregation = r.Element("Congregation").Value,
                      TalkNumber = r.Element("TalkNumber").Value,
                      MeetingDate = DateTime.Parse(r.Element("MeetingDate").Value)
                  }).ToList() // ?? new () can be added if you don't want AwayTalks property to be null
    }