3

我正在尝试构建一个选择唯一值组的查询。我知道如何对值进行分组并选择不同的值,但我不知道如何选择不同的值组,而不管考虑的元素的顺序如何。更确切地说:

我的 XML 是这样的:

<A>
    <B type="1">value1</prop>
    <B type="2">value2</prop>
    <B type="3">value3</prop>
    <B type="4">value4</prop>
<C>
    <D>XXX</D>
</C>
<C>
    <D>YYY</D>
</C>
</A>

<A>
    <B type="3">value3</prop>
    <B type="4">value4</prop>
    <B type="2">value2</prop>
<C>
    <D>XXX</D>
</C>
<C>
    <D>YYY</D>
</C>
</A>

在这里,我想<B>从所有<A>节点中创建一组值,并只选择唯一的一组值。例如,这里:

值1+值2+值3+值4

值2+值3+值4+值1

仅当部分或全部值不同时,这两组值才应该是唯一的。

非常感谢您的帮助。

4

2 回答 2

2

以下作品:

var doc = XDocument.Parse(xml);

var comparer = new ElementsComparer();

var result = doc.Descendants("B")
                .GroupBy(x => x.Parent)
                .Distinct(comparer);

class ElementsComparer : IEqualityComparer<IGrouping<XElement, XElement>>,
                         IEqualityComparer<XElement>
{
    public bool Equals(XElement lhs, XElement rhs)
    {
        return lhs.Value.Equals(rhs.Value);
    }

    public bool Equals(IGrouping<XElement, XElement> lhs,
                       IGrouping<XElement, XElement> rhs)
    {
        var x = lhs.OrderBy(a => a.Value);
        var y = rhs.OrderBy(a => a.Value);
        return x.SequenceEqual(y, this);
    }

    public int GetHashCode(XElement obj)
    {
        return obj.Value.GetHashCode();
    }

    public int GetHashCode(IGrouping<XElement, XElement> obj)
    {
        return 0;
    }
}

这将返回不同的组。如果组中的元素与另一组中的元素具有相同的值,则该组被视为与另一组相同。
不幸的是,我们需要一个完整的IEqualityComparer实现来实现这一点。

于 2012-09-24T10:50:02.720 回答
0

尝试

var xDocument = XDocument.Parse(/*Your XML here*/);
var vals =
    //Find all A-Elements
    xDocument.Root.Elements("A")
        //Select all their B-Elements to one collection
        .SelectMany(a => a.Elements("B"))
        //Group the B-Items by their value
        .GroupBy(element => element.Value)
        //Select the keys of the IGrouping<TValue, XElement>
        .Select(element => element.Key)
        //Distinct them
        .Distinct();
于 2012-09-24T10:39:28.623 回答