Search code examples
c#asp.netlinqlinq-to-xmlxelement

How to put a self join with LINQ on XDocument?


I have XDocument randomly containing few records in this format :

<Course>
  <CourseId>21</CourseId>
  <CourseName>leaf</CourseName>
  <CourseDesc>This course</CourseDesc>
  <Event>
    <EventName>Dallas, US - August 19, 2013</EventName>
    <EventStart>2013-08-19T00:00:00-04:00</EventStart>
    <EventEnd>2013-08-23T00:00:00-04:00</EventEnd>
  </Event>
  <Event>
    <EventName>Texas, US - August 19, 2013</EventName>
    <EventStart>2013-08-19T00:00:00-04:00</EventStart>
    <EventEnd>2013-08-23T00:00:00-04:00</EventEnd>
  </Event>
  <Event>
    <EventName>NY, US - August 19, 2013</EventName>
    <EventStart>2013-08-19T00:00:00-04:00</EventStart>
    <EventEnd>2013-08-23T00:00:00-04:00</EventEnd>
  </Event>
</Course>

(Generally <Event> node occurs just once)

I need to extract/Select/Filter them as :

<Course>
      <CourseId>21</CourseId>
      <CourseName>leaf</CourseName>
      <CourseDesc>This course</CourseDesc>
      <Event>
        <EventName>Dallas, US - August 19, 2013</EventName>
        <EventStart>2013-08-19T00:00:00-04:00</EventStart>
        <EventEnd>2013-08-23T00:00:00-04:00</EventEnd>
      </Event>
</Course>
 <Course>
      <CourseId>21</CourseId>
      <CourseName>leaf</CourseName>
      <CourseDesc>This course</CourseDesc>
      <Event>
        <EventName>Texas, US - August 19, 2013</EventName>
        <EventStart>2013-08-19T00:00:00-04:00</EventStart>
        <EventEnd>2013-08-23T00:00:00-04:00</EventEnd>
      </Event>
</Course>
 <Course>
      <CourseId>21</CourseId>
      <CourseName>leaf</CourseName>
      <CourseDesc>This course</CourseDesc>
      <Event>
        <EventName>NY, US - August 19, 2013</EventName>
        <EventStart>2013-08-19T00:00:00-04:00</EventStart>
        <EventEnd>2013-08-23T00:00:00-04:00</EventEnd>
      </Event>
</Course>

Solution

  • Try this:

    var query =
        doc
            .Root
            .Descendants("Event")
            .Select(e =>
                new XElement(
                    "Course",
                    e.Parent.Element("CourseId"),
                    e.Parent.Element("CourseName"),
                    e.Parent.Element("CourseDesc"),
                    e));
    

    It's simple and it worked for me.