I am trying to populate my own object from a XElement
:
MidweekMeetingHistoryItem oItem = new MidweekMeetingHistoryItem
{
Week = datHistoryItemWeekOfMeeting,
Chairman = nodeHistoryItem.Element("Chairman")?.Value,
AuxCounsellor1 = nodeHistoryItem.Element("AuxCounsellor1")?.Value,
AuxCounsellor2 = nodeHistoryItem.Element("AuxCounsellor2")?.Value,
TeachingMain = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 0).Value,
TeachingAux1 = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 1).Value,
TeachingAux2 = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 2).Value,
};
It has several more properties, all of which read fine. The issue is here:
TeachingMain = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 0).Value,
TeachingAux1 = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 1).Value,
TeachingAux2 = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 2).Value,
In my XML data, a week that has no Teaching items looks liek this:
<Teaching/>
If it has one class, it looks like this:
<Teaching>
<Name Class="0">xxx</Name>
</Teaching>
If 2 classes:
<Teaching>
<Name Class="0">xxx</Name>
<Name Class="1">yyy</Name>
</Teaching>
And if three:
<Teaching>
<Name Class="0">xxx</Name>
<Name Class="1">yyy</Name>
<Name Class="2">zzz</Name>
</Teaching>
I was hoping that the code:
TeachingMain = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 0).Value,
TeachingAux1 = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 1).Value,
TeachingAux2 = nodeHistoryItem.Element("Teaching")?.Elements("Name")?.Single(x => (int?)x.Attribute("Class") == 2).Value,
Would simply set the name if it existed, else, set it as empty. But I am getting exceptions:
<LogEntry Date="2022-05-16 13:35:42" Severity="Exception" Source="MSAToolsLibrary.MSAToolsLibraryClass.ExtractFutureMidweekAssignments" ThreadId="1">
<Exception Type="System.InvalidOperationException" Source="System.Linq.Enumerable.Single">
<Message>Sequence contains no matching element</Message>
<StackTrace> at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at MSAToolsLibrary.MSAToolsLibraryClass.ExtractFutureMidweekAssignments(DateTime datWeekOfMeeting, String strHistoryDatabase) in D:\My Programs\2022\MSAToolsLibrary\MSAToolsLibrary\MSAToolsLibraryClass.cs:line 1467</StackTrace>
</Exception>
</LogEntry>
How do I fix that?
At the moment I have added some more verbose code, after the initial populating of the properties:
var oTeaching = nodeHistoryItem.Element("Teaching");
if(oTeaching != null)
{
if(oTeaching.HasElements)
{
var oName = oTeaching.Elements("Name")
.Where(x => x.Attribute("Class").Value == "0").First();
if (oName != null)
{
oItem.TeachingMain = oName.Value;
}
oName = oTeaching.Elements("Name")
.Where(x => x.Attribute("Class").Value == "1").First();
if (oName != null)
{
oItem.TeachingAux1 = oName.Value;
}
oName = oTeaching.Elements("Name")
.Where(x => x.Attribute("Class").Value == "2").First();
if (oName != null)
{
oItem.TeachingAux2 = oName.Value;
}
}
}
That works, but I was hoping to use something similar to what I was trying to do before.
The MidweekMeetingHistoryItem
defined like this:
[Guid("~~~~")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class MidweekMeetingHistoryItem : IMidweekMeetingHistoryItem
{
public DateTime Week { get; set; }
public string Chairman { get; set; }
public string AuxCounsellor1 { get; set; }
public string AuxCounsellor2 { get; set; }
public string OpeningPrayer { get; set; }
public string Treasures1 { get; set; }
public string Treasures2 { get; set; }
public string TeachingMain { get; set; }
public string TeachingAux1 { get; set; }
public string TeachingAux2 { get; set; }
public string Living1 { get; set; }
public string Living2 { get; set; }
public string Living3 { get; set; }
public string CBSConductor { get; set; }
public string CBSReader { get; set; }
public string ConcludingPrayer { get; set; }
public string Host { get; set; }
public string Cohost { get; set; }
}