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从我开始。
我该怎么做呢?
您正在按名称&标题,所以你得到的唯一的组是你已经得到的。
你需要把你的名字按标题分组,然后你会得到一组包含有相同标题的名字的分组。
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));
}
}
}