我有一个XML,我正在尝试使用LINQ to XML解析并将其转换为匿名的对象列表。为此,我想出了以下代码片段:
var res = doc
.Root
.Elements("Record")
.Elements("Term")
.Select(term => new
{
LanguageCode = term.Attribute("languageCode").Value,
ConceptNumber = Convert.ToInt32(term.Attribute("conceptNumber").Value),
IsHidden = Convert.ToBoolean(term.Attribute("hidden").Value),
Label = term.Value,
InputDate = DateTime.Parse(term.Parent.Element("InputDate").Value),
LastUpdate = DateTime.Parse(term.Parent.Element("LastUpdated").Value)
}).ToList();
请注意InputDate& LastUpdate部分。如您所见,我将访问父节点(例如,term.Parent),以便我可以访问这两个元素,这看起来很混乱。有没有办法声明term.Parent一次并反复使用它来提取这些属性?
以下是我正在尝试阅读的XML的摘录:
<Record>
<Term languageCode="Prs" conceptNumber="10" hidden="False">Whatever</Term>
<Status>Approved</Status>
<Frequency>0</Frequency>
<InputDate>12/30/1899</InputDate>
<LastUpdate>10/25/2009</LastUpdate>
</Record>
谢谢
答案 0 :(得分:6)
您需要使用let
clause。它在查询中创建一个新变量,并允许多次使用它。
在你的情况下,它将是
var res = (from term in doc.Root.Elements("Record").Elements("Term")
let parent = term.Parent
select new
{
LanguageCode = term.Attribute("languageCode").Value,
ConceptNumber = Convert.ToInt32(term.Attribute("conceptNumber").Value),
IsHidden = Convert.ToBoolean(term.Attribute("hidden").Value),
Label = term.Value,
InputDate = parent.Element("InputDate").Value,
LastUpdate = parent.Element("LastUpdated").Value
}).ToList();
请注意,它是一个纯LINQ语法的代码,可以让您比使用问题中的扩展方法更清晰地表达想法。
答案 1 :(得分:1)
您可以在投影中引入一个匿名类(这类似于let
在幕后的内容),然后使用SelectMany()
使用额外属性展平:
var results = doc.Elements("Record")
.Select( x => new
{
Terms = x.Elements("Term"),
InputDate = DateTime.Parse(x.Element("InputDate").Value),
LastUpdate = DateTime.Parse(x.Element("LastUpdate").Value)
})
.SelectMany(x => x.Terms, (record,term) => new
{
LanguageCode = term.Attribute("languageCode").Value,
..
InputDate = record.InputDate,
LastUpdate = record.LastUpdate
});