2009-06-15 105 views
0

我有一个XML配置文件,其中包含文档列表以及每个文档的字段映射。我想用LINQ to XML填充一个内部数据结构,它将文档表示为列表层次结构。如何从XML中使用一个LINQ查询填充父级和子级结构中的父级子级数据结构?

一个名为Include的属性确定是否应包含该字段。

这里的XML是什么样子的样本:

<Documents> 
    <Document Include="1" DocumentName="Report1" > 
    <Field Include="1" OldName="Old1" NewName="New1"/> 
    <Field Include="1" OldName="Old2" NewName="New2"/> 
    <Field Include="0" OldName="Old3" NewName="New3"/> 
    </Document> 
    <Document Include="1" DocumentName="Report2" > 
    <Field Include="1" OldName="Old1" NewName="New1"/> 
    <Field Include="0" OldName="Old3" NewName="New3"/> 
    </Document> 
</Documents> 

代表文件的数据结构是这样的:

class FieldMap 
{ 
    public string OldName { get; set; } 
    public string NewName { get; set; } 
} 

class Document 
{ 
    public string DocumentName { get; set; } 
    public List<FieldMap> FieldMaps; 
} 

private List<Document> Documents; 

下面是代码,我有做第一部分通过填写文件:

var ds = from row in elem.Descendants("Document") 
     where row.Attribute("Include").Value == "1" 
     select new Document 
     { 
      DocumentName = row.Attribute("DocumentName").Value, 
     }; 

Documents = ds.ToList<Document>(); 

我想修改上面的代码,以便它也填充每个Document中的List结构。我知道我可以通过遍历文档列表<>并在循环中运行另一个LINQ查询来完成此操作,但是我宁愿将所有内容都作为统一查询来完成。

+0

抵制在一个查询中做所有事情的冲动。它的(可以说)是一种阅读的痛苦,而测试或调试无疑是一种痛苦。 – 2009-06-15 17:25:10

+0

@Frank,我不同意。在这种情况下,使用子查询是有意义的,并且比仅对结果使用foreach循环来填充list属性更清晰。如果你认为foreach循环更容易测试/调试,那么继续使用它们,但我没有看到阻止LINQ中的子查询的理由。 – CoderDennis 2009-06-15 18:08:14

回答

2

你有没有尝试过这样的事情?

var ds = from row in elem.Descendants("Document") 
     where row.Attribute("Include").Value == "1" 
     select new Document 
     { 
      DocumentName = row.Attribute("DocumentName").Value, 
      FieldMaps = //Solution from here 
       (from field in row.Descendants ("Field") 
       where field.Attribute("Include").Value == "1" 
       select new FieldMap { 
        OldName = field.Attribute("OldName").Value, 
        NewName = field.Attribute("NewName").Value 
       }).ToList() //To here 
     }; 

Documents = ds.ToList<Document>(); 

有人说,这是更清楚popullate使用foreach LINQ查询外FielMaps性能,我不同意这个观点,但如果你喜欢,替代它看起来就像是这样的:

var ds = from row in elem.Descendants("Document") 
     where row.Attribute("Include").Value == "1" 
     select new Document 
     { 
      DocumentName = row.Attribute("DocumentName").Value 
     }; 

Documents = ds.ToList<Document>(); 

foreach (var document in Documents) 
    document.FieldMaps = elem.Descendants("Document") 
     .Where(doc => doc.Attributes("DocumentName") == document.DocumentName) 
     .Select(doc => doc.Descendants("Fields")) 
     .Where(field => field.Attributes("Include").Value == "1") 
     .Select(field => new FieldMap 
      { 
       OldName = field.Attributes("OldName").Value, 
       newName = field.Attributes("NewName").Value 
      } 
     ).ToList(); 
相关问题