Помогите с linq to xml запросом
Помогите с linq to xml запросом. Есть вот такой xml
<Security Version="1.0">
<Bond SecurityID="1">
<Name>Arconic Inc. 5.9 01/02/27</Name>
<EngName>Arconic Inc. 5.9 01/02/27</EngName>
<Brief>ARNC 5.9 02/01/27</Brief>
<InstrumentGroup>Bonds</InstrumentGroup>
<ISIN>US013817AJ05</ISIN>
<RegNumber></RegNumber>
<EndServiceDate>1900-01-01</EndServiceDate>
<Nominal>1000.00000000000000</Nominal>
<SecStatusList>
<SecStatus Brief="ДляКвалИнв" Name="Предназначен для квалифицированных инвесторов" SecStatusID="1" SysType="1" SecStatusTypeID="2">
<DateStart>2019-01-18</DateStart>
<DateEnd>2050-01-01</DateEnd>
<Comment />
</SecStatus>
</SecStatusList>
</Bond>
</Security>
Есть класс:
public class Bonds
{
public int? Id { get; set; }
public string? ISIN { get; set; }
public string? RegNumber { get; set; }
public string Name { get; set; }
public string? NameEn { get; set; }
public decimal? Nominal { get; set; }
public DateTime? ExpireDay { get; set; }
public bool? IsQualifiedInvestors { get; set; }
}
Написала запрос для всех полей кроме IsQualifiedInvestors (если есть узел с Brief="ДляКвалИнв", то тогда проставляем true, иначе - false). Не пойму как правильно его написать.
var doc = XDocument.Load(@".\bond.xml");
List<Bonds> bonds = (from _sec in doc.Element("Security").Elements("Bond")
select new Bonds
{
Id = XmlConvert.ToInt64(_sec.Attribute("SecurityID").Value),
ISIN = _sec.Element("ISIN").Value,
RegNumber = _sec.Element("RegNumber").Value,
Name = _sec.Element("Name").Value,
NameEn = _sec.Element("EngName").Value,
Nominal = XmlConvert.ToDecimal(_sec.Element("Nominal").Value),
ExpireDay = XmlConvert.ToDateTime(_sec.Element("EndServiceDate").Value),
//IsForQualifiedInvestors
}
).ToList();
foreach (var bond in bonds)
{
Console.WriteLine("{0}: {1}, {2}, {3}", bond.Name, bond.Nominal, bond.BeansId,bond.ExpireDay);
}
Ответы (1 шт):
var bonds = (from bond in doc.Element("Security").Elements("Bond")
select new Bond
{
Id = (int?)bond.Attribute("SecurityID"),
ISIN = bond.Element("ISIN")?.Value,
RegNumber = bond.Element("RegNumber")?.Value,
Name = bond.Element("Name").Value,
NameEn = bond.Element("EngName")?.Value,
Nominal = (decimal?)bond.Element("Nominal"),
ExpireDay = (DateTime?)bond.Element("EndServiceDate"),
IsQualifiedInvestors = bond.Element("SecStatusList")?.Element("SecStatus")?.Attribute("Brief")?.Value == "ДляКвалИнв"
}
).ToList();
Класс я бы переименовал в Bond - всё-таки должно быть единственное число. А коллекция - bonds.
Вместо XmlConvert, который относится к другому API, в linq2xml принято использовать приведение типов: (int?)bond.Attribute("SecurityID").
Строковые значения тоже можно приводить: (string?)bond.Element("ISIN"), но вариант с .Value таки короче.
Так как свойства заданы как nullable, то используем ?.Value, (int?), (decimal?) и т. д.
Свойство Name объявлено non-nullable, поэтому, чтобы избежать возможных ошибок, если в XML не окажется такого узла, следует использовать код наподобие:
Name = bond.Element("Name")?.Value ?? "",
где вместо "" указать дефолтное значение.