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

时间:2016-07-09 13:59:05

标签: c#

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

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

A  1  str1 1001
A  1  str2 1002
A  1  str2 1003
B  2  str3 1004
B  2  str3 1005

输出xml dta应如下所示:

<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>
...

这里是模型定义

public class foo
    {
        public string letter { get; set; }
        public string order { get; set; }
        public string title { get; set; }
        public string titleid { get; set; }
    }

如何使用上面的模型列表预先设置这个xml文件?

2 个答案:

答案 0 :(得分:2)

您可以使用LINQ对数据进行分组。为了使此代码正常工作,我重命名了foo类型Foo,这样我就可以拥有名为foo的变量。变量foosFoo个对象的集合。

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;

正如您所看到的,序列首先被分组为复合键letterorder,然后在每个外部组中Foo个对象按title分组。

通过使用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)
            )
          )
        )
      )
    )
  )
);

答案 1 :(得分:1)

假设数据按以下方式排序:letter =&gt; title =&gt; 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>");

希望它有所帮助!