编辑:为了更加清晰和高效,更新了代码并采用ToDictionary
方法。
您可以尝试以下示例。如果从select new Record
行中移除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")
};
Func
方法更快。而且我觉得这种方式更易读。 - Ahmad Mageed