cyboashu cyboashu - 3 months ago 20
C# Question

How to add OR condition in LINQ while querying XML?

Problem: return all records

where
Jon Doe
=<bus_contact>
OR
<bus_sponsor>
.

Current code returns record 1, so what modifications are required to return records 1 and 2 using just one query?.

XML

<root>
<row>
<project_id>1</project_id>
<project_name>Name1</project_name>
<bus_contact>Jon Doe</bus_contact>
<bus_sponsor>Bruce Wayne</bus_sponsor>
</row>
<row>
<project_id>2</project_id>
<project_name>Name2</project_name>
<bus_contact>Peter Parker</bus_contact>
<bus_sponsor>Jon Doe</bus_sponsor>
</row>
</root>


C#

class Program
{
static void Main (string[] args)
{
XElement main = XElement.Load ("master_list.xml");

var results = main.Descendants ("row")
.Descendants ("bus_contact")
.Where (e => e.Value == "Jon Doe")
.Select (e => e.Parent)
.Select (e => new {
project_id = e.Descendants ("project_id").FirstOrDefault ().Value,
project_name = e.Descendants ("project_name").FirstOrDefault ().Value
});

foreach (var result in results)
Console.WriteLine ("{0}, {1}", result.project_id, result.project_name);
Console.ReadLine ();
}
}


Edit : This is not exactly the same problem as pointed out in the possible duplicate link. Yes, it partially refers to that but as a beginner getting an answer with appropriate context, which the accepted answer provides, is quite helpful.

Answer

Use || in combination with Any, like this:

var results = main.Descendants("row")
    .Where(r =>
        r.Descendants("bus_contact").Any(c => c.Value == "Jon Doe")
    ||  r.Descendants("bus_sponsor").Any(c => c.Value == "Jon Doe")
    );

Using Any lets you query by a condition on a child, without actually descending to the child level. This eliminated necessity to climb the tree back by selecting Parent.