Если вы не доверяете порядку свойств, вы можете попробовать что-то вроде этого:
var metadata = doc.Root.Element("metadata");
var mapper = metadata.Elements("item")
.Select((i, c) => new { Property = i.Attribute("name").Value, Index = c })
.ToDictionary(i => i.Property, i => i.Index);
var rows = doc.Root.Element("data").Elements("row").Select(r => new GroupDto
{
Date = r.Elements("value").ElementAt(mapper[nameof(GroupDto.Date)]).Value,
Hour = r.Elements("value").ElementAt(mapper[nameof(GroupDto.Hour)]).Value,
Group = r.Elements("value").ElementAt(mapper[nameof(GroupDto.Group)]).Value,
Status = r.Elements("value").ElementAt(mapper[nameof(GroupDto.Status)]).Value,
}).ToList();
Возможно, это не самое оптимальное решение, но оно дает вам то, что вы хотите -сложный способ.
Вдобавок ко всему, если ваши свойства в вашем xml не будут соответствовать свойствам вашего объекта DTO, вы всегда можете ввести дополнительный слой сопоставления. Например:
var metaMapper = metadata.Elements(ns + "item")
.Select((i, c) => new { Property = i.Attribute("name").Value, Index = c })
.ToDictionary(i => i.Property, i => i.Index);
var metaPropertyMapper = new Dictionary<string, string>
{
{ nameof(GroupDto.Date), "DateInXML" },
{ nameof(GroupDto.Hour), "HourInXML" },
{ nameof(GroupDto.Group), "GroupInXML" },
{ nameof(GroupDto.Status), "StatusInXML" },
};
var rows = doc.Root.Element(ns + "data").Elements(ns + "row").Select(r => new GroupDto
{
Date = r.Elements(ns + "value").ElementAt(metaMapper[metaPropertyMapper[nameof(GroupDto.Date)]]).Value,
Hour = r.Elements(ns + "value").ElementAt(metaMapper[metaPropertyMapper[nameof(GroupDto.Hour)]]).Value,
Group = r.Elements(ns + "value").ElementAt(metaMapper[metaPropertyMapper[nameof(GroupDto.Group)]]).Value,
Status = r.Elements(ns + "value").ElementAt(metaMapper[metaPropertyMapper[nameof(GroupDto.Status)]]).Value,
}).ToList();