c# Xml分组,更好的可视化

本文关键字:可视化 更好 Xml 分组 | 更新日期: 2023-09-27 18:19:25

我有这个xml

<Group>
    <Day name="Mo">
        <title>Foo</title>
    </Day>
    <Day name="Tu">
        <title>Foo</title>
        <title>Bar</title>
    </Day>
    <Day name="We">
        <title>Foo</title>
    </Day>
    <Day name="Su">
        <title>Foo</title>
    </Day>
</Group>

我想这样转换这个XML

<Group>
    <Day name="Mo,Tu,We,Th,Su"> <!-- notice the repetition of tuesday -->
        <title>Foo</title>
    </Day>
    <Day name="Tu">
        <title>Bar</title>
    </Day>
</Group>

,以便使用LINQ to XML更好地可视化。我知道这两个xml在逻辑上是不一样的,但我已经实现了我的系统而不关心它。

我一直在尝试使用这个LINQ查询分组元素

var grp = from d in source.Element("Grp").Elements("Day")
          group d by new { name = d.Attribute("name"), value = d.Elements("title")
           into g
           select g;

但我注意到,我得到的是有点相同的xml从我开始。

我该怎么做呢?

c# Xml分组,更好的可视化

您正在按名称&标题,所以你得到的唯一的组是你已经得到的。

你需要把你的名字按标题分组,然后你会得到一组包含有相同标题的名字的分组。

var groupings = from day in doc.Descendants("Day")
                let name = (string)day.Attribute("name")
                from title in day.Elements("title")
                group name by title.Value;

你可以用这些来创建一些新的元素:

var elements = from grouping in groupings
               let title = grouping.Key
               let names = string.Join(",", grouping)
               select new XElement("Day",
                   new XAttribute("name", names),
                   new XElement("title", title)
                   );

然后为这些元素创建一个新的容器:

var result = new XDocument(
    new XElement("Group",
        elements
        )
    );

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication53
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<Root>" + 
                    "<Group>" +
                        "<Day name='"Mo'">" +
                            "<title>Foo</title>" +
                        "</Day>" +
                        "<Day name='"Tu'">" +
                            "<title>Foo</title>" +
                            "<title>Bar</title>" +
                        "</Day>" +
                        "<Day name='"We'">" +
                            "<title>Foo</title>" +
                        "</Day>" +
                        "<Day name='"Su'">" +
                            "<title>Foo</title>" +
                        "</Day>" +
                    "</Group>" +
                 "</Root>";
            XElement root = XElement.Parse(xml);
            var groups = root.Descendants("Group").Elements("Day").Select(x => new
            {
                titles = x.Descendants("title").Select(y => new {
                   day = x.DescendantsAndSelf().FirstOrDefault(),
                   title = (string)y
                }).ToList()
            }).SelectMany(z => z.titles).GroupBy(a => a.title).Select(b => new XElement("Day", new object[] {
                    new XAttribute("name", string.Join(",", b.Select(c => c.day.Attribute("name").Value).ToArray())),
                    new XElement("title",b.FirstOrDefault().title)
                })).ToList();
            root.Element("Group").ReplaceWith(new XElement("Group", groups));


        }
    }
}