简体   繁体   English

您如何使用一个LINQ查询从XML填充父子数据结构,而通用List <>对象位于父子结构中?

[英]How do you populate a parent child data structure from XML where generic List<> objects are in parent and child structures using one LINQ query?

I have an XML configuration file that contains a list of documents with field maps for each document. 我有一个XML配置文件,其中包含文档列表以及每个文档的字段映射。 I want to use LINQ to XML to populate an internal data structure which represents the documents as a hierarchy of List<> structures. 我想使用LINQ to XML填充内部数据结构,该结构将文档表示为List <>结构的层次结构。

An attribute called Include determines whether the field should be included. 名为Include的属性确定是否应包含该字段。

Here is a sample of what the XML looks like: 这是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>

The datastructure representing the documents looks like this: 表示文档的数据结构如下所示:

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;

Below is code I have that does the first part by populating the 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>();

I would like to modify the code above so that it also populates the List structure within each Document. 我想修改上面的代码,以便它也可以填充每个Document中的List结构。 I know I could do this by iterating through the Documents List<> and running another LINQ query in the loop however I would prefer to do everything as a consolidated query. 我知道我可以通过遍历Documents List <>并在循环中运行另一个LINQ查询来做到这一点,但是我更愿意将所有内容作为统一查询来进行。

Have you tried something like this: ? 您是否尝试过以下方法?

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>();

Some people says that it's clearer to popullate the FielMaps properties outside the LINQ query using a foreach, i don't agree with that, but if you like that alternative it would look like something like: 有人说,使用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM