C# 使用Linq将列表分组到子列表

C# 使用Linq将列表分组到子列表,c#,C#,我有从csv文件加载的对象列表,我的目标是将其写入xml并下载 以下是原始csv文件数据,如下所示: A 1 str1 1001 A 1 str2 1002 A 1 str2 1003 B 2 str3 1004 B 2 str3 1005 <MyHeader> <columnHeader1 foo='A' order='1'> <columnHeader2 title="str1"> <colu

我有从csv文件加载的对象列表,我的目标是将其写入xml并下载

以下是原始csv文件数据,如下所示:

A  1  str1 1001
A  1  str2 1002
A  1  str2 1003
B  2  str3 1004
B  2  str3 1005
<MyHeader>
   <columnHeader1 foo='A' order='1'>
      <columnHeader2 title="str1">
         <columnHeader3 id="1001"/>
      </columnHeader2>
      <columnHeader2 title="str2">
          <columnHeader3 id="1002" />
          <columnHeader3 id="1003" />
      </columnHeader2>
   </columnHeader1>
<columnHeader1 foo='B' order='2'>
      <columnHeader2 title="str3">
         <columnHeader3 id="1004"/>
         <columnHeader3 id="1005"/>
      </columnHeader2>
   </columnHeader1>
...
输出xml dta应如下所示:

A  1  str1 1001
A  1  str2 1002
A  1  str2 1003
B  2  str3 1004
B  2  str3 1005
<MyHeader>
   <columnHeader1 foo='A' order='1'>
      <columnHeader2 title="str1">
         <columnHeader3 id="1001"/>
      </columnHeader2>
      <columnHeader2 title="str2">
          <columnHeader3 id="1002" />
          <columnHeader3 id="1003" />
      </columnHeader2>
   </columnHeader1>
<columnHeader1 foo='B' order='2'>
      <columnHeader2 title="str3">
         <columnHeader3 id="1004"/>
         <columnHeader3 id="1005"/>
      </columnHeader2>
   </columnHeader1>
...

如何使用上面的模型列表预显示此xml文件?

假设数据按以下方式排序:字母=>title=>id

最简单的解决方案可能是仅使用循环和StringBuilder连接字符串:

StringBuilder xmlBuilder = new StringBuilder();
string letter = string.Empty;
string title = string.Empty;

xmlBuilder.Append("<MyHeader>");

foreach (foo item in foos)
{
    if (title != string.Empty && item.title != title)
    {
        xmlBuilder.Append("</columnHeader2>");
    }

    if (letter != string.Empty && item.letter != letter)
    {
        xmlBuilder.Append("</columnHeader1>");
    }

    if (item.letter != letter)
    {
        letter = item.letter;
        xmlBuilder.AppendFormat("<columnHeader1 foo='{0}' order='{1}'>", item.letter, item.order);
    }

    if (item.title != title)
    {
        title = item.title;
        xmlBuilder.AppendFormat("<columnHeader2 title=\"{0}\">", item.tile);
    }

    xmlBuilder.AppendFormat("<columnHeader3 id=\"{0}\" />", item.titleid)
}

xmlBuilder.Append("</columnHeader2>");
xmlBuilder.Append("</columnHeader1>");
xmlBuilder.Append("</MyHeader>");
StringBuilder xmlBuilder=new StringBuilder();
string字母=string.Empty;
string title=string.Empty;
xmlBuilder.Append(“”);
foreach(foos中的foo项)
{
if(title!=string.Empty&&item.title!=title)
{
xmlBuilder.Append(“”);
}
if(字母!=string.Empty&&item.letter!=letter)
{
xmlBuilder.Append(“”);
}
如果(item.letter!=字母)
{
字母=item.letter;
xmlBuilder.AppendFormat(“”,item.letter,item.order);
}
如果(item.title!=标题)
{
title=item.title;
xmlBuilder.AppendFormat(“,item.tile”);
}
xmlBuilder.AppendFormat(“,item.titleid)
}
xmlBuilder.Append(“”);
xmlBuilder.Append(“”);
xmlBuilder.Append(“”);

希望有帮助

假设数据按以下方式排序:字母=>title=>id

最简单的解决方案可能是仅使用循环和StringBuilder连接字符串:

StringBuilder xmlBuilder = new StringBuilder();
string letter = string.Empty;
string title = string.Empty;

xmlBuilder.Append("<MyHeader>");

foreach (foo item in foos)
{
    if (title != string.Empty && item.title != title)
    {
        xmlBuilder.Append("</columnHeader2>");
    }

    if (letter != string.Empty && item.letter != letter)
    {
        xmlBuilder.Append("</columnHeader1>");
    }

    if (item.letter != letter)
    {
        letter = item.letter;
        xmlBuilder.AppendFormat("<columnHeader1 foo='{0}' order='{1}'>", item.letter, item.order);
    }

    if (item.title != title)
    {
        title = item.title;
        xmlBuilder.AppendFormat("<columnHeader2 title=\"{0}\">", item.tile);
    }

    xmlBuilder.AppendFormat("<columnHeader3 id=\"{0}\" />", item.titleid)
}

xmlBuilder.Append("</columnHeader2>");
xmlBuilder.Append("</columnHeader1>");
xmlBuilder.Append("</MyHeader>");
StringBuilder xmlBuilder=new StringBuilder();
string字母=string.Empty;
string title=string.Empty;
xmlBuilder.Append(“”);
foreach(foos中的foo项)
{
if(title!=string.Empty&&item.title!=title)
{
xmlBuilder.Append(“”);
}
if(字母!=string.Empty&&item.letter!=letter)
{
xmlBuilder.Append(“”);
}
如果(item.letter!=字母)
{
字母=item.letter;
xmlBuilder.AppendFormat(“”,item.letter,item.order);
}
如果(item.title!=标题)
{
title=item.title;
xmlBuilder.AppendFormat(“,item.tile”);
}
xmlBuilder.AppendFormat(“,item.titleid)
}
xmlBuilder.Append(“”);
xmlBuilder.Append(“”);
xmlBuilder.Append(“”);

希望有帮助

您可以使用LINQ对数据进行分组。为了使此代码正常工作,我重命名了您的
foo
类型
foo
,这允许我将变量命名为
foo
。变量
foos
Foo
对象的集合

var groupedData = from foo in foos
                  group foo by new { foo.letter, foo.order } into outerGroup
                  from innerGroup in
                       (from foo in outerGroup
                        group foo by foo.title)
                  group innerGroup by outerGroup.Key;
如您所见,序列首先按组合键
字母
顺序
分组,然后在每个外部组中,
Foo
对象按
标题
分组

通过使用LINQ to XML,您可以将分组数据转换为分层XML:

var root = new XElement(
  "MyHeader",
  groupedData.Select(
    outerGroup => new XElement(
      "columnHeader1",
      new XAttribute("foo", outerGroup.Key.letter),
      new XAttribute("order", outerGroup.Key.order),
      outerGroup.Select(
        innerGroup => new XElement(
          "columnHeader2",
          new XAttribute("title", innerGroup.Key),
          innerGroup.Select(
            foo => new XElement(
              "columnHeader3",
              new XAttribute("id", foo.titleid)
            )
          )
        )
      )
    )
  )
);

您可以使用LINQ对数据进行分组。为了使此代码正常工作,我重命名了您的
foo
类型
foo
,这允许我将变量命名为
foo
。变量
foos
Foo
对象的集合

var groupedData = from foo in foos
                  group foo by new { foo.letter, foo.order } into outerGroup
                  from innerGroup in
                       (from foo in outerGroup
                        group foo by foo.title)
                  group innerGroup by outerGroup.Key;
如您所见,序列首先按组合键
字母
顺序
分组,然后在每个外部组中,
Foo
对象按
标题
分组

通过使用LINQ to XML,您可以将分组数据转换为分层XML:

var root = new XElement(
  "MyHeader",
  groupedData.Select(
    outerGroup => new XElement(
      "columnHeader1",
      new XAttribute("foo", outerGroup.Key.letter),
      new XAttribute("order", outerGroup.Key.order),
      outerGroup.Select(
        innerGroup => new XElement(
          "columnHeader2",
          new XAttribute("title", innerGroup.Key),
          innerGroup.Select(
            foo => new XElement(
              "columnHeader3",
              new XAttribute("id", foo.titleid)
            )
          )
        )
      )
    )
  )
);

有几种方法可以做到这一点,但是在问这个问题之前,你尝试过做什么?您是如何读取CSV文件的?您是如何尝试编写XML的?如果是这样的话,也许我们可以帮助您解决问题。我建议您看看csv帮助器:--这将允许您迭代csv文档中的记录,在这一点上,您可以将它们作为“foo”类装箱,并将它们添加到列表中。然后查询、分组、输出。但我和Dandre在一起,到目前为止我做了什么?@Dandré我只需要像上面那样将foo列表写入xmk文件,我已经读取并加载数据到列表中。我使用的是简单的xmlserializer,但我的数据格式必须如上所述。@PimBrouwers我想我需要将title和titleid分离到'bar'类中,并将其列表作为属性添加到foo('list barlits{get;set;}')中。你的意思是这样的吗?TyForHelpDude,那么你不知道如何将某些内容序列化为XML,或者你尝试了一些方法但没有成功吗?因为有很多选项可以将对象序列化为XML:XML序列化程序、XML文档对象(然后对其调用Save),即使只是简单地将XML写入字符串然后将其写入文件也可以(但最不可取)。有两种方法可以做到这一点,但在问这个问题之前,您尝试过做什么?您是如何读取CSV文件的?您是如何尝试编写XML的?如果是这样的话,也许我们可以帮助您解决问题。我建议您看看csv帮助器:--这将允许您迭代csv文档中的记录,在这一点上,您可以将它们作为“foo”类装箱,并将它们添加到列表中。然后查询、分组、输出。但我和Dandre在一起,到目前为止我做了什么?@Dandré我只需要像上面那样将foo列表写入xmk文件,我已经读取并加载数据到列表中。我使用的是简单的xmlserializer,但我的数据格式必须如上所述。@PimBrouwers我想我需要将title和titleid分离到'bar'类中,并将其列表作为属性添加到foo('list barlits{get;set;}')中。你的意思是这样的吗?TyForHelpDude,那么你不知道如何将某些内容序列化为XML,或者你尝试了一些方法但没有成功吗?因为有很多选项可以将对象序列化为XML:XML序列化程序、XML文档对象(然后对其调用Save),即使只是简单地将XML写入字符串,然后将其写入文件也可以(但这是最不可取的)。尽管这对您当前的解决方案简单有效,但还是要看看XML序列化。这将节省您在XML中添加另一个字段的大量时间,而不是查看字符串并找出由于额外字段而需要更改的字符串