Filtering out duplicate XElements based on an attribute value from a Linq query
我正在使用 Linq 尝试过滤掉任何与 "name" 属性具有相同值的重复 XElement。
原始xml:
1 2 3 4 5 6 7 8 | <foo> <property name="John" value="Doe" id="1" /> <property name="Paul" value="Lee" id="1" /> <property name="Ken" value="Flow" id="1" /> <property name="Jane" value="Horace" id="1" /> <property name="Paul" value="Lee" id="1" /> ... other xml properties with different id's </foo> |
1 2 3 4 5 6 7 8 9 10 | // project elements in group into a new XElement // (this is for another part of the code) var props = group.data.Select( f => new XElement("property", new XAttribute("name", f.Attribute("name").Value), f.Attribute("value")); // filter out duplicates props = props.Where(f => f.ElementsBeforeSelf() .Where(g => g.Attribute("name").Value == f.Attribute("name").Value) .Count() == 0); |
很遗憾,过滤步骤不起作用。我认为 Where() 过滤器会检查当前元素之前具有相同属性名称的任何元素,然后将其包含在大于零的集合中,从而排除当前元素(称为 \\'f\\'),但那没有发生。想法?
您可以创建一个 IEqualityComparer 与 Distinct() 一起使用,这应该可以满足您的需求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Program { static void Main(string[] args) { string xml ="<foo><property name="John" value="Doe" id="1"/><property name="Paul" value="Lee" id="1"/><property name="Ken" value="Flow" id="1"/><property name="Jane" value="Horace" id="1"/><property name="Paul" value="Lee" id="1"/></foo>"; XElement x = XElement.Parse(xml); var a = x.Elements().Distinct(new MyComparer()).ToList(); } } class MyComparer : IEqualityComparer<XElement> { public bool Equals(XElement x, XElement y) { return x.Attribute("name").Value == y.Attribute("name").Value; } public int GetHashCode(XElement obj) { return obj.Attribute("name").Value.GetHashCode(); } } |
我认为您应该先删除重复项,然后再进行投影。例如:
1 2 3 4 5 6 |
或者,如果您更喜欢方法语法,
1 2 3 4 5 6 |
您的方法有点奇怪,例如,您不需要将元素投影到新元素中;当您将现有元素添加到新文档时,它才有效(tm)。
我将简单地按
1 2 3 4 5 6 |