/
rezvich
/
SoapBatchProcessor
Обзор
Документация
Войти
/
rezvich
/
SoapBatchProcessor
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Parsing/HistoryResponseParser.cs
498 строк
25 KB
rezvich
Подправил токен
04 авг 2026, 12:20
04 авг 2026, 12:20
632636d
Код
Авторство
О чём код?
using SoapBatchProcessor.Infrastructure; using SoapBatchProcessor.Models.Data_Models; using SoapBatchProcessor.Models.SOAP; using System.Xml; namespace SoapBatchProcessor.Parsing { public static class HistoryResponseParser { public static SoapResponseDto Parse(string externalRequestId, string xml) { var dto = new SoapResponseDto { ExternalRequestId = externalRequestId, Success = true, OmsPolicies = new(), Dudls = new(), Addresses = new(), Attachments = new(), Contacts = new(), SocialStatuses = new() }; var doc = new XmlDocument(); doc.LoadXml(xml); var ns = XmlNs.CreateNsMgr(doc.NameTable); // SOAP Fault? var fault = doc.SelectSingleNode("//*[local-name()='Body']/*[local-name()='Fault']"); if (fault != null) { dto.Success = false; dto.ErrorMessage = fault.SelectSingleNode("faultstring")?.InnerText ?? "SOAP Fault"; return dto; } // Принимаем оба варианта ответа var resp = doc.SelectSingleNode("//*[local-name()='Body']/*[local-name()='getPersonDataResponse']") ?? doc.SelectSingleNode("//*[local-name()='Body']/*[local-name()='getPersonDataHistoryResponse']"); if (resp == null) { dto.Success = false; dto.ErrorMessage = "getPersonDataResponse/getPersonDataHistoryResponse not found"; return dto; } var errorItems = resp.SelectNodes(".//*[local-name()='errors']/*[local-name()='errorItem']"); if (errorItems != null && errorItems.Count > 0) { var msgs = new List<string>(); foreach (XmlNode e in errorItems) { var code = e.SelectSingleNode("*[local-name()='code']")?.InnerText; var msg = e.SelectSingleNode("*[local-name()='message']")?.InnerText; var tag = e.SelectSingleNode("*[local-name()='tag']")?.InnerText; var val = e.SelectSingleNode("*[local-name()='value']")?.InnerText; msgs.Add($"{code}: {msg} [{tag}] {val}"); } return new SoapResponseDto { ExternalRequestId = externalRequestId, Success = false, ErrorMessage = string.Join(" | ", msgs) }; } var container = resp.SelectSingleNode("*[local-name()='pd']") ?? resp; var oip = container.SelectSingleNode(".//*[local-name()='oip']")?.InnerText; // ---- NEW: items-схема ---- // Person (берём первый personItems) var personItems = container.SelectNodes(".//*[local-name()='personItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>(); var personItem = personItems .Select(p => new { Node = p, DateEdit = LD(p, "dateEdit") ?? DateTime.MinValue }) .OrderByDescending(x => x.DateEdit) .FirstOrDefault() ?.Node; if (personItem != null) { dto.Person = ParsePersonItems(personItem); dto.Person.Oip = oip; } // policy/policyItems -> OmsPolicyData foreach (var it in container.SelectNodes(".//*[local-name()='policyItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.OmsPolicies.Add(ParsePolicyItems(it)); // dudl/dudlItems -> DudlData foreach (var it in container.SelectNodes(".//*[local-name()='dudlItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Dudls.Add(ParseDudlItems(it)); // attach/attachItems -> AttachData foreach (var it in container.SelectNodes(".//*[local-name()='attachItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Attachments.Add(ParseAttachItems(it)); // address/addressItems foreach (var it in container.SelectNodes(".//*[local-name()='addressItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Addresses.Add(ParseAddressItems(it)); // contact/contactItems foreach (var it in container.SelectNodes(".//*[local-name()='contactItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Contacts.Add(ParseContactItems(it)); // snils/snilsItems var snItems = container.SelectSingleNode(".//*[local-name()='snilsItems']"); if (snItems != null) dto.Snils = ParseSnilsItems(snItems); // socialStatus/socialStatusItems foreach (var it in container.SelectNodes(".//*[local-name()='socialStatusItems']")?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.SocialStatuses.Add(ParseSocialItems(it)); // ern/ernItems var ernItems = container.SelectSingleNode(".//*[local-name()='ernItems']"); if (ernItems != null) dto.Ern = ParseErnItems(ernItems); // ---- Fallback: старая (плоская) схема, если items не нашли вообще ---- bool hasAny = dto.Person != null || dto.OmsPolicies.Count > 0 || dto.Dudls.Count > 0 || dto.Addresses.Count > 0 || dto.Attachments.Count > 0 || dto.Contacts.Count > 0 || dto.Snils != null || dto.SocialStatuses.Count > 0 || dto.Ern != null; if (!hasAny) { // Старые XPaths, (с префиксами mpip/com) var personNode = container.SelectNodes(".//mpip:Person", ns)?.Cast<XmlNode>().FirstOrDefault(); if (personNode != null) { dto.Person = ParsePerson(personNode, ns); dto.Person.Oip = oip; } if (dto.Person == null && !string.IsNullOrWhiteSpace(oip)) //Если Person пустой засунем OIP { dto.Person = new PersonData { Oip = oip, BirthDay = DateTime.MinValue, WhenMerged = DateTime.MinValue, DateEdit = DateTime.MinValue }; } foreach (var n in container.SelectNodes(".//mpip:OmsPolicy", ns)?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.OmsPolicies.Add(ParsePolicy(n, ns)); foreach (var n in container.SelectNodes(".//mpip:Dudl", ns)?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Dudls.Add(ParseDudl(n, ns)); foreach (var n in container.SelectNodes(".//mpip:Address", ns)?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Addresses.Add(ParseAddress(n, ns)); foreach (var n in container.SelectNodes(".//mpip:Attach", ns)?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Attachments.Add(ParseAttach(n, ns)); foreach (var n in container.SelectNodes(".//mpip:Contact", ns)?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.Contacts.Add(ParseContact(n, ns)); var sn = container.SelectSingleNode(".//mpip:Snils", ns); if (sn != null) dto.Snils = ParseSnils(sn, ns); foreach (var n in container.SelectNodes(".//mpip:SocialStatus", ns)?.Cast<XmlNode>() ?? Enumerable.Empty<XmlNode>()) dto.SocialStatuses.Add(ParseSocial(n, ns)); var ern = container.SelectSingleNode(".//mpip:Ern", ns); if (ern != null) dto.Ern = new ErnData { Ern = ern.SelectSingleNode("mpip:ern", ns)?.InnerText, DsourceType = ern.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, Dsource = ern.SelectSingleNode("mpip:dsource", ns)?.InnerText, ErnStatus = ern.SelectSingleNode("mpip:ernStatus", ns)?.InnerText }; } return dto; } private class XmlNodeListAdapter : System.Collections.IEnumerable { public System.Collections.IEnumerator GetEnumerator() { yield break; } } private static string? L(XmlNode n, string local) => n.SelectSingleNode($".//*[local-name()='{local}']")?.InnerText; private static DateTime? LD(XmlNode n, string local) { var s = L(n, local); return DateTime.TryParse(s, out var dt) ? dt : null; } private static PersonData ParsePersonItems(XmlNode it) => new() { Oip = L(it, "oip"), FirstName = L(it, "firstName"), Surname = L(it, "surname"), Patronymic = L(it, "patronymic"), BirthDay = LD(it, "birthDay") ?? DateTime.MinValue, Gender = L(it, "gender"), BirthOksm = L(it, "birthOksm"), DeathDate = LD(it, "deathDate"), WhenMerged = LD(it, "whenMerged") ?? DateTime.MinValue, Status = L(it, "status"), DateEdit = LD(it, "dateEdit") ?? DateTime.MinValue }; private static OmsPolicyData ParsePolicyItems(XmlNode it) => new() { Enp = L(it, "enp"), PcySer = L(it, "pcySer"), PcyNum = L(it, "pcyNum"), EnpCalc = L(it, "enpCalc"), PcyDateB = LD(it, "pcyDateB") ?? DateTime.MinValue, PcyDateE = LD(it, "pcyDateE"), PcyDateH = LD(it, "pcyDateH"), PcyDateT = LD(it, "pcyDateT"), PcyDateEnpCalc = LD(it, "pcyDateEnpCalc"), PcyDatePr = LD(it, "pcyDatePr"), PcyType = L(it, "pcyType"), PcyStatus = L(it, "pcyStatus"), Okato = L(it, "okato"), Dsource = L(it, "dsource"), DsourceType = L(it, "dsourceType"), Descr = L(it, "descr"), Gender = L(it, "gender"), InsurName = L(it, "insurName"), InsurfName = L(it, "insurfName"), InsurOgrn = L(it, "insurOgrn"), InsurfOgrn = L(it, "insurfOgrn"), InsurCode = L(it, "insurCode"), InsurfCode = L(it, "insurfCode"), InsurfDate = LD(it, "insurfDate"), TmpCertNum = L(it, "tmpCertNum"), TmpCertDateB = LD(it, "tmpCertDateB"), TmpCertDateE = LD(it, "tmpCertDateE"), UekNum = L(it, "uekNum"), PcyCategory = L(it, "pcyCategory"), Surname = L(it, "surname"), Patronymic = L(it, "patronymic"), FirstName = L(it, "firstName"), BirthDay = LD(it, "birthDay"), BlankNum = L(it, "blankNum") }; private static DudlData ParseDudlItems(XmlNode it) => new() { DudlSer = L(it, "dudlSer"), DudlNum = L(it, "dudlNum"), DudlDateB = LD(it, "dudlDateB") ?? DateTime.MinValue, DudlDateE = LD(it, "dudlDateE"), DudlType = L(it, "dudlType"), Issuer = L(it, "issuer"), IssuerOksm = L(it, "issuerOksm"), CtznOksm = L(it, "ctznOksm"), NoCitizenship = string.Equals(L(it, "noCitizenship"), "true", StringComparison.OrdinalIgnoreCase), Dsource = L(it, "dsource"), Descr = L(it, "descr"), Surname = L(it, "surname"), Patronymic = L(it, "patronymic"), FirstName = L(it, "firstName"), BirthDay = LD(it, "birthDay"), Birthplace = L(it, "birthplace"), Gender = L(it, "gender"), DsourceType = L(it, "dsourceType"), BirthOksm = L(it, "birthOksm"), DudlStatus = L(it, "dudlStatus"), Dost = L(it, "dost"), DudlCodeDivision = L(it, "dudlCodeDivision") }; private static AttachData ParseAttachItems(XmlNode it) => new() { AreaType = L(it, "areaType"), AreaId = L(it, "areaId"), AttachMethod = L(it, "attachMethod"), MCapitation = int.TryParse(L(it, "mCapitation") ?? "", out var mc) ? mc : 0, DateAttachB = LD(it, "dateAttachB") ?? DateTime.MinValue, DateAttachE = LD(it, "dateAttachE"), MoId = L(it, "moId"), MoCode = L(it, "moCode"), MoFId = L(it, "moFId"), SnilsDoctor = L(it, "snilsDoctor"), DoctorId = L(it, "doctorId"), DoctorSince = LD(it, "doctorSince"), Descr = L(it, "descr"), MoOkato = L(it, "moOkato"), AttachStatus = L(it, "attachStatus"), Dsource = L(it, "dsource"), DsourceType = L(it, "dsourceType"), DepId = L(it, "depId") }; private static AddressData ParseAddressItems(XmlNode it) => new() { Okato = L(it, "okato"), Oksm = L(it, "oksm"), Aoguid = L(it, "aoguid"), Hsguid = L(it, "hsguid"), AddressText = L(it, "addressText"), MailIndex = L(it, "mailIndex"), AppNum = L(it, "appNum"), DsourceType = L(it, "dsourceType"), Dsource = L(it, "dsource"), AddressType = L(it, "addressType"), AddressDateB = LD(it, "addressDateB") ?? DateTime.MinValue, AddressDateE = LD(it, "addressDateE"), AddressStatus = L(it, "addressStatus") }; private static ContactData ParseContactItems(XmlNode it) => new() { ContactType = L(it, "contactType"), Descr = L(it, "descr"), ContactText = L(it, "contactText"), DsourceType = L(it, "dsourceType"), Dsource = L(it, "dsource"), ContactStatus = L(it, "contactStatus") }; private static SocialStatusData ParseSocialItems(XmlNode it) => new() { SocialStatus = L(it, "socialStatus"), DsourceType = L(it, "dsourceType"), Dsource = L(it, "dsource"), Descr = L(it, "descr"), RegDate = LD(it, "regDate") ?? DateTime.MinValue }; private static SnilsData ParseSnilsItems(XmlNode it) => new() { Snils = L(it, "snils"), Dsource = L(it, "dsource"), DsourceType = L(it, "dsourceType"), Descr = L(it, "descr"), StatusSnils = L(it, "statusSnils") }; private static ErnData ParseErnItems(XmlNode it) => new() { Ern = L(it, "ern"), Dsource = L(it, "dsource"), DsourceType = L(it, "dsourceType"), ErnStatus = L(it, "ernStatus") }; private static PersonData ParsePerson(XmlNode n, XmlNamespaceManager ns) => new() { Oip = n.SelectSingleNode("mpip:oip", ns)?.InnerText, FirstName = n.SelectSingleNode("mpip:firstName", ns)?.InnerText, Surname = n.SelectSingleNode("mpip:surname", ns)?.InnerText, Patronymic = n.SelectSingleNode("mpip:patronymic", ns)?.InnerText, BirthDay = ParseDate(n.SelectSingleNode("mpip:birthDay", ns)?.InnerText) ?? DateTime.MinValue, Gender = n.SelectSingleNode("mpip:gender", ns)?.InnerText, BirthOksm = n.SelectSingleNode("mpip:birthOksm", ns)?.InnerText, DeathDate = ParseDate(n.SelectSingleNode("mpip:deathDate", ns)?.InnerText), WhenMerged = ParseDate(n.SelectSingleNode("mpip:whenMerged", ns)?.InnerText) ?? DateTime.MinValue, Status = n.SelectSingleNode("mpip:status", ns)?.InnerText, DateEdit = ParseDate(n.SelectSingleNode("mpip:dateEdit", ns)?.InnerText) ?? DateTime.MinValue }; private static OmsPolicyData ParsePolicy(XmlNode n, XmlNamespaceManager ns) => new() { PcySer = n.SelectSingleNode("mpip:pcySer", ns)?.InnerText, PcyNum = n.SelectSingleNode("mpip:pcyNum", ns)?.InnerText, EnpCalc = n.SelectSingleNode("mpip:enpCalc", ns)?.InnerText, Enp = n.SelectSingleNode("mpip:enp", ns)?.InnerText, PcyDateB = ParseDate(n.SelectSingleNode("mpip:pcyDateB", ns)?.InnerText) ?? DateTime.MinValue, PcyDateE = ParseDate(n.SelectSingleNode("mpip:pcyDateE", ns)?.InnerText), PcyDateH = ParseDate(n.SelectSingleNode("mpip:pcyDateH", ns)?.InnerText), PcyDateT = ParseDate(n.SelectSingleNode("mpip:pcyDateT", ns)?.InnerText), PcyDateEnpCalc = ParseDate(n.SelectSingleNode("mpip:pcyDateEnpCalc", ns)?.InnerText), PcyDatePr = ParseDate(n.SelectSingleNode("mpip:pcyDatePr", ns)?.InnerText), PcyType = n.SelectSingleNode("mpip:pcyType", ns)?.InnerText, PcyStatus = n.SelectSingleNode("mpip:pcyStatus", ns)?.InnerText, Okato = n.SelectSingleNode("mpip:okato", ns)?.InnerText, Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, Descr = n.SelectSingleNode("mpip:descr", ns)?.InnerText, Gender = n.SelectSingleNode("mpip:gender", ns)?.InnerText, InsurName = n.SelectSingleNode("mpip:insurName", ns)?.InnerText, InsurfName = n.SelectSingleNode("mpip:insurfName", ns)?.InnerText, InsurOgrn = n.SelectSingleNode("mpip:insurOgrn", ns)?.InnerText, InsurfOgrn = n.SelectSingleNode("mpip:insurfOgrn", ns)?.InnerText, InsurCode = n.SelectSingleNode("mpip:insurCode", ns)?.InnerText, InsurfCode = n.SelectSingleNode("mpip:insurfCode", ns)?.InnerText, InsurfDate = ParseDate(n.SelectSingleNode("mpip:insurfDate", ns)?.InnerText), TmpCertNum = n.SelectSingleNode("mpip:tmpCertNum", ns)?.InnerText, TmpCertDateB = ParseDate(n.SelectSingleNode("mpip:tmpCertDateB", ns)?.InnerText), TmpCertDateE = ParseDate(n.SelectSingleNode("mpip:tmpCertDateE", ns)?.InnerText), UekNum = n.SelectSingleNode("mpip:uekNum", ns)?.InnerText, PcyCategory = n.SelectSingleNode("mpip:pcyCategory", ns)?.InnerText, Surname = n.SelectSingleNode("mpip:surname", ns)?.InnerText, Patronymic = n.SelectSingleNode("mpip:patronymic", ns)?.InnerText, FirstName = n.SelectSingleNode("mpip:firstName", ns)?.InnerText, BirthDay = ParseDate(n.SelectSingleNode("mpip:birthDay", ns)?.InnerText), BlankNum = n.SelectSingleNode("mpip:blankNum", ns)?.InnerText }; private static DudlData ParseDudl(XmlNode n, XmlNamespaceManager ns) => new() { DudlSer = n.SelectSingleNode("mpip:dudlSer", ns)?.InnerText, DudlNum = n.SelectSingleNode("mpip:dudlNum", ns)?.InnerText, DudlDateB = ParseDate(n.SelectSingleNode("mpip:dudlDateB", ns)?.InnerText) ?? DateTime.MinValue, DudlDateE = ParseDate(n.SelectSingleNode("mpip:dudlDateE", ns)?.InnerText), DudlType = n.SelectSingleNode("mpip:dudlType", ns)?.InnerText, Issuer = n.SelectSingleNode("mpip:issuer", ns)?.InnerText, IssuerOksm = n.SelectSingleNode("mpip:issuerOksm", ns)?.InnerText, CtznOksm = n.SelectSingleNode("mpip:ctznOksm", ns)?.InnerText, NoCitizenship = (n.SelectSingleNode("mpip:noCitizenship", ns)?.InnerText == "true"), Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, Descr = n.SelectSingleNode("mpip:descr", ns)?.InnerText, Surname = n.SelectSingleNode("mpip:surname", ns)?.InnerText, Patronymic = n.SelectSingleNode("mpip:patronymic", ns)?.InnerText, FirstName = n.SelectSingleNode("mpip:firstName", ns)?.InnerText, BirthDay = ParseDate(n.SelectSingleNode("mpip:birthDay", ns)?.InnerText), Birthplace = n.SelectSingleNode("mpip:birthplace", ns)?.InnerText, Gender = n.SelectSingleNode("mpip:gender", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, BirthOksm = n.SelectSingleNode("mpip:birthOksm", ns)?.InnerText, DudlStatus = n.SelectSingleNode("mpip:dudlStatus", ns)?.InnerText, Dost = n.SelectSingleNode("mpip:dost", ns)?.InnerText, DudlCodeDivision = n.SelectSingleNode("mpip:dudlCodeDivision", ns)?.InnerText }; private static AddressData ParseAddress(XmlNode n, XmlNamespaceManager ns) => new() { Okato = n.SelectSingleNode("mpip:okato", ns)?.InnerText, Oksm = n.SelectSingleNode("mpip:oksm", ns)?.InnerText, Aoguid = n.SelectSingleNode("mpip:aoguid", ns)?.InnerText, Hsguid = n.SelectSingleNode("mpip:hsguid", ns)?.InnerText, AddressText = n.SelectSingleNode("mpip:addressText", ns)?.InnerText, MailIndex = n.SelectSingleNode("mpip:mailIndex", ns)?.InnerText, AppNum = n.SelectSingleNode("mpip:appNum", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, AddressType = n.SelectSingleNode("mpip:addressType", ns)?.InnerText, AddressDateB = ParseDate(n.SelectSingleNode("mpip:addressDateB", ns)?.InnerText) ?? DateTime.MinValue, AddressDateE = ParseDate(n.SelectSingleNode("mpip:addressDateE", ns)?.InnerText), AddressStatus = n.SelectSingleNode("mpip:addressStatus", ns)?.InnerText }; private static AttachData ParseAttach(XmlNode n, XmlNamespaceManager ns) => new() { AreaType = n.SelectSingleNode("mpip:areaType", ns)?.InnerText, AreaId = n.SelectSingleNode("mpip:areaId", ns)?.InnerText, AttachMethod = n.SelectSingleNode("mpip:attachMethod", ns)?.InnerText, MCapitation = int.TryParse(n.SelectSingleNode("mpip:mCapitation", ns)?.InnerText, out var mc) ? mc : 0, DateAttachB = ParseDate(n.SelectSingleNode("mpip:dateAttachB", ns)?.InnerText) ?? DateTime.MinValue, DateAttachE = ParseDate(n.SelectSingleNode("mpip:dateAttachE", ns)?.InnerText), MoId = n.SelectSingleNode("mpip:moId", ns)?.InnerText, MoCode = n.SelectSingleNode("mpip:moCode", ns)?.InnerText, MoFId = n.SelectSingleNode("mpip:moFId", ns)?.InnerText, SnilsDoctor = n.SelectSingleNode("mpip:snilsDoctor", ns)?.InnerText, DoctorId = n.SelectSingleNode("mpip:doctorId", ns)?.InnerText, DoctorSince = ParseDate(n.SelectSingleNode("mpip:doctorSince", ns)?.InnerText), Descr = n.SelectSingleNode("mpip:descr", ns)?.InnerText, MoOkato = n.SelectSingleNode("mpip:moOkato", ns)?.InnerText, AttachStatus = n.SelectSingleNode("mpip:attachStatus", ns)?.InnerText, Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, DepId = n.SelectSingleNode("mpip:depId", ns)?.InnerText }; private static ContactData ParseContact(XmlNode n, XmlNamespaceManager ns) => new() { ContactType = n.SelectSingleNode("mpip:contactType", ns)?.InnerText, Descr = n.SelectSingleNode("mpip:descr", ns)?.InnerText, ContactText = n.SelectSingleNode("mpip:contactText", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, ContactStatus = n.SelectSingleNode("mpip:contactStatus", ns)?.InnerText }; private static SnilsData ParseSnils(XmlNode n, XmlNamespaceManager ns) => new() { Snils = n.SelectSingleNode("mpip:snils", ns)?.InnerText, Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, Descr = n.SelectSingleNode("mpip:descr", ns)?.InnerText, StatusSnils = n.SelectSingleNode("mpip:statusSnils", ns)?.InnerText }; private static SocialStatusData ParseSocial(XmlNode n, XmlNamespaceManager ns) => new() { SocialStatus = n.SelectSingleNode("mpip:socialStatus", ns)?.InnerText, DsourceType = n.SelectSingleNode("mpip:dsourceType", ns)?.InnerText, Dsource = n.SelectSingleNode("mpip:dsource", ns)?.InnerText, Descr = n.SelectSingleNode("mpip:descr", ns)?.InnerText, RegDate = ParseDate(n.SelectSingleNode("mpip:regDate", ns)?.InnerText) ?? DateTime.MinValue }; private static DateTime? ParseDate(string? s) => DateTime.TryParse(s, out var dt) ? dt : null; } }