我有这样的菜单xml:
<root>
<item name="submenu" href="">
<item name="delete post" href="example.com/delete" />
**<item name="delete post" href="" />**
**<item name="add post" href="" />**
<item name="add post" href="example.com/add" />
**<item name="add post" href="" />**
<item name="do not remove" href="" />
</item>
<item name="list post" href="example.com/list" />
**<item name="list post" href="" />**
<item name="remove only one of these" href="" />
**<item name="remove only one of these" href="" />**
</root>
我需要删除重复的项目并在此处找到解决方案: efficiently removing duplicate xml elements in c#
我的问题是,如果要填充href
,我想保留这个确切的记录-因此,我需要在分组之后但在删除记录之前对它们进行排序。
因此,我需要删除标记有**
的记录,但无法使OrderBy(string.IsNullOrWhiteSpace)
与GroupBy
一起工作。
任何帮助表示赞赏。
答案 0 :(得分:1)
这是您要找的吗?
public class Item
{
public string Name { get; set; }
public string Href { get; set; }
}
class Program
{
static void Main(string[] args)
{
var data = new List<Item>
{
new Item { Name="1", Href="" },
new Item { Name="1", Href="b" },
new Item { Name="2", Href="c" },
new Item { Name="2", Href="" },
new Item { Name="2", Href="" },
};
var results = data.OrderBy(d => d.Name).ThenByDescending(d => d.Href).GroupBy(d => d.Name).Select(g => g.First());
foreach (var result in results)
{
Console.WriteLine(result.Name + ", " + result.Href);
}
Console.ReadLine();
}
}
结果是:
1,b
2,c
答案 1 :(得分:1)
这对在所有条件下都能正常工作的xml的递归性质而言,并不是一个简单的问题。您需要使用类似下面的代码的递归方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication67
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement root = doc.Root;
RemoveRecursive(root);
}
static void RemoveRecursive(XElement element)
{
var groups = element.Elements()
.GroupBy(x => new { tagname = x.Name.LocalName, itemname = (string)x.Attribute("name") })
.Select(x => x.Select(y => new { element = y, index = (string)y.Attribute("href") == "" ? 0 : 1 })).ToList();
foreach(var group in groups)
{
var orderGroup = group.OrderByDescending(x => x.index).ToList();
for (int i = orderGroup.Count() - 1; i > 0; i--)
{
orderGroup[i].element.Remove();
}
}
foreach(XElement child in element.Elements())
{
if (child.HasElements) RemoveRecursive(child);
}
}
}
}