Compiler: Visual Studio 2019
Framework: .Net 2.1
Given a XML file like this:
<root>
<data>
<AdditionalOrderInfo>
<AdditionalInfoItem key="{4567B566-A0A2-4214-B7E7-814FE179CDFC}" value="ScanItDental"/>
<AdditionalInfoItem key="GlobalOrderID" value="EDC531BE6A0D4DC5BFEA0C6081D9F26B"/>
<AdditionalInfoItem key="CreatedIn" value="2.20.1.2"/>
</AdditionalOrderInfo>
</data>
</root>
I need to get AdditionalInfoItem
only for certain key
values.
To avoid null errors I'm trying to use nullable types and coalesce operator ??
var additionalOrderInfo = document.Descendants(ns "AdditionalOrderInfo").First();
var value = additionalOrderInfo.Descendants(ns "AdditionalInfoItem")?.Where(el => el.Attribute("key").Value == "SomeKey")?.First()?.Attribute("value")?.Value ?? "";
But if key
doesn't exists it returns:
Sequence contains no elements.
I've ended using a foreach
loop in this way:
var additionalOrderInfo = document.Descendants(ns "AdditionalOrderInfo").First();
foreach (var item in additionalOrderInfo.Descendants(ns "AdditionalInfoItem"))
{
switch (item.Attribute("key").Value)
{
case "SomeKey1":
Order.SomeKey1 = item.Attribute("value").Value;
break;
case "SomeKey2":
Order.SomeKey2 = item.Attribute("value").Value;
break;
}
}
Is there a way to avoid the foreach
loop and read the value using a single line of code?
CodePudding user response:
Try use FirstOrDefault
instead of First
only after Where
selector:
var value = additionalOrderInfo.Descendants(ns "AdditionalInfoItem")?
.Where(el => el.Attribute("key").Value == "SomeKey")?
.FirstOrDefault()? // <--- Here
.Attribute("value")?.Value ?? "";
If Where(el => el?.Attribute("key")?.Value == "SomeKey")
return 0 elements, you getting Sequence contains no elements
exception, so you can't get First
element of it. FirstOrDefault
returns null
instead, so next nullcheck ?
goes forward.