score:3

EDIT: Okay, edited again. I think this is okay, but even with your sample file it would be nice if you could give us a concrete example of inputs and expected outputs:

// Extension methods
internal static bool IsBidder(this XElement bidder, string person)
{
    return (string) bidder.Element("personref")
        .Attribute("person") == person;
}

internal static IEnumerable<XElement> ElementsAfterFirst
    (this IEnumerable<XElement> source, XName name)
{
    var first = source.FirstOrDefault();
    if (first != null)
    {
        foreach (var element in first.ElementsAfterSelf(name))
        {
            yield return element;
        }
    }
}

var query = doc
    .Descendants("open_auction")
        .Where(x => x.Elements("bidder")
               // All the person20 bids...
               .Where(b => b.IsBidder("person20"))
               // Now project to bids after the first one...
               .ElementsAfterFirst("bidder")
               // Are there any from person51? If so, include this auction.
               .Any(b => b.IsBidder("person51"))
               );

The second extension method can also be written as:

internal static IEnumerable<XElement> ElementsAfterFirst
    (this IEnumerable<XElement> source, XName name)
{
    var first = source.FirstOrDefault();
    return first == null ? new XElement[0] : first.ElementsAfterSelf(name);
}

It changes the timing slightly, but it shouldn't make any difference in this particular case...

score:0

Thx a lot Jon! Your code helped me a lot to learn this concept of Linq to XML Ok, I have made a query without any helper methods, which works fine. I have formated a bit unusal but it might help other noops like me who take a look here to understand what is going on:

 List<XElement> i = XMarkXML.Element("site").Element("open_auctions").Descendants("open_auction")
        .Where(x => (x.Element("bidder") != null )
                    &&
                    (x.Elements("bidder").Any(b => (b.Element("personref").Attribute("person").Value == "person540")))
                    &&
                    (
                      x.Elements("bidder").Where(
                                                 b1 => (b1.Element("personref").Attribute("person").Value == "person540")
                                                 ).First().ElementsAfterSelf("bidder").Any(
                                                                                            b2 => (b2.Element("personref").Attribute("person").Value == "person1068")
                                                                                            )
                    )
               ).ToList();

When taking actions on Collections, it is important, that there is something inside, so it is important to check if Collection.Count() != 0. After that it is possible to do the query.


Related Articles