Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add OR condition in LINQ while querying XML?

Tags:

c#

xml

linq

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.

like image 707
cyboashu Avatar asked Aug 09 '16 16:08

cyboashu


2 Answers

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.

like image 144
Sergey Kalinichenko Avatar answered Oct 21 '22 13:10

Sergey Kalinichenko


If each row element has only one subelement item of each kind (bus_contact, bus_sponsor, etc.) you can simplify the whole query by using Element method instead of Descendants

var results =
    main.Descendants ("row")
    .Where (r => r.Element("bus_contact").Value == "Jon Doe"
              || r.Element("bus_contact").Value == "Jon Doe")
    .Select (r => new {
        project_id = r.Element("project_id").Value,
        project_name = r.Element("project_name").Value
    });
like image 31
Sehnsucht Avatar answered Oct 21 '22 12:10

Sehnsucht