Образец XML (исходная ссылка):
Sven
infinity2
12/15/2009
Josephine
infinity3
01/02/2010
Frankie
wk-infinity9
10/02/2009
Я желаю получить экземпляр класса на запись в xml.
я нашел подобные примеры в здесь, но у них только был корень, затем один элемент глубоко. Это работает, до тех пор, пока я не вставил тот другой элемент. я хочу смочь сделать что-то как
foreach(Record rec in myVar)
{
Console.WriteLine("ID: {0} User:{1} Domain:{2} LastLogon:{3}",rec.Index, rec.Username, rec.Domain, rec.LastLogon);
}
РЕДАКТИРОВАТЬ: обновленный код с подходом ToDictionary
для ясности и эффективности.
Вы можете попробовать следующий образец. Если вы удалите запись
из строки select new Record
, это приведет к анонимному типу и по-прежнему будет работать.Ваш класс Record
должен иметь конструктор без параметров по умолчанию для использования инициализатора объекта, если вы предоставили другие конструкторы (он также будет работать, если у вас нет конструкторов). В противном случае вы можете использовать доступные конструкторы вместо инициализатора объекта.
Обратите внимание, что использование Single ()
и Value
предполагает, что XML правильно сформирован без каких-либо пропущенных элементов.
var xml = XElement.Parse(@"<records>
<record index=""1"">
<property name=""Username"">Sven</property>
<property name=""Domain"">infinity2</property>
<property name=""LastLogon"">12/15/2009</property>
</record>
<record index=""2"">
<property name=""Username"">Josephine</property>
<property name=""Domain"">infinity3</property>
<property name=""LastLogon"">01/02/2010</property>
</record>
<record index=""3"">
<property name=""Username"">Frankie</property>
<property name=""Domain"">wk-infinity9</property>
<property name=""LastLogon"">10/02/2009</property>
</record>
</records>");
var query = from record in xml.Elements("record")
let properties = record.Elements("property")
.ToDictionary(p => p.Attribute("name").Value, p => p.Value)
select new Record
{
Index = record.Attribute("index").Value,
Username = properties["Username"],
Domain = properties["Domain"],
LastLogon = properties["LastLogon"]
};
foreach(var rec in query)
{
Console.WriteLine("ID: {0} User:{1} Domain:{2} LastLogon:{3}", rec.Index, rec.Username, rec.Domain, rec.LastLogon);
}
РЕДАКТИРОВАТЬ: Я обновил приведенный выше пример кода с помощью подхода ToDictionary
, который стал чище и быстрее. Судя по моим усилиям по тестированию, самым быстрым был ToDictionary
, затем Func
, а затем подход Where
.
Исходный запрос
var query = from record in xml.Elements("record")
let properties = record.Elements("property")
select new Record
{
Index = record.Attribute("index").Value,
Username = properties.Where(p => p.Attribute("name").Value == "Username").Single().Value,
Domain = properties.Where(p => p.Attribute("name").Value == "Domain").Single().Value,
LastLogon = properties.Where(p => p.Attribute("name").Value == "LastLogon").Single().Value
};
Запрос с функцией
Избыточность исходного запроса можно уменьшить, используя следующий код:
Func<XElement, string, string> GetAttribute =
(e, property) => e.Elements("property")
.Where(p => p.Attribute("name").Value == property)
.Single().Value;
var query = from record in xml.Elements("record")
select new Record
{
Index = record.Attribute("index").Value,
Username = GetAttribute(record, "Username"),
Domain = GetAttribute(record, "Domain"),
LastLogon = GetAttribute(record, "LastLogon")
};