如何获得所有的“属性”,从XML通过LINQ为xml
问题描述:
XML样本(original link):如何获得所有的“属性”,从XML通过LINQ为xml
<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>
我想在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
,它将导致匿名类型并仍然有效。你的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键
可以通过下面的代码可以减少原始查询的冗余:
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")
};
PERFICT!我一直试图找出现在2-3天。我的前途是疼痛和红色。你推荐哪些书来调节LINQ(和C#)。 – 2010-02-24 05:43:33
@Sunzaru我喜欢LINQ in Action(http://www.amazon.com/dp/1933988169/),或者您可能希望获得一本C#4.0/.NET 4.0书籍来涵盖一些新的材料。简单的C#4.0是很好的,但它涵盖了大量的材料。我还推荐下载LINQPad(http://www.linqpad.net/)并浏览它附带的Nutshell样本(由本书作者制作)。您也可以通过它下载LINQ in Action示例。也许在购买书籍之前先做到这一点:) – 2010-02-24 05:52:37
我今天测试过,平均处理时间为120MS。但在那些120MS中,我还在寻找其他一些没有提到的指标。快速..光滑和zomg .. sooo比“编辑 - >查找”更好。再次感谢! – 2010-02-25 01:04:49