我有这个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相同。
我对如何做到这一点有任何想法?
答案 0 :(得分:0)
您按姓名分组&amp;标题,所以你得到的唯一独特的群体就是你已经拥有的那些。
您需要按标题对名称进行分组,然后您最终会得到包含一堆具有相同标题的名称的分组。
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
)
);
您可以在this fiddle中看到一个有效的例子。
答案 1 :(得分:0)
试试这个
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));
}
}
}