how to traverse parent node till root element in xml in c#

I am trying to access parent node hierarchy till root element from child element in C# and want to store it in string.

In the below xml, I would like to access parent nodes of the <watchVideo> element but I don't want to include the root tag in my string and the output should be like this:

herobanner.landing.copies.watchvideo

My xml format is:

<?xml version="1.0"?>
<root>  
  <country>en-in</country>
  <heroBanner>
    <landing>
      <copies>
        <watchVideo>watch the video</watchVideo>
        <scrollDown>READ INSPIRING STORIES</scrollDown>
        <scrollDown/>
        <banner>make your</banner>
        <banner>first move this</banner>
        <banner>valentine's Day</banner>
      </copies>
      <background>
        <desktop>assets/images/millions-hero-1.jpg</desktop>
      </background>
      <foreground>
        <desktop/>
      </foreground>
      <video>
        <youtubeId>buwcDIcFR8I</youtubeId>
      </video>
    </landing>
  </heroBanner>
</root>
Jon Skeet
people
quotationmark

Well, to get from one XElement to its parent, you can just use the Parent property - but in this case you want all the ancestors, so you can use the AncestorsAndSelf() method. That returns the ancestors in reverse document order, but you want it in document order (outermost first) so you can just reverse the sequence. Then you know the first element will be the root - you can skip that by calling Skip(1). Then you just need to select the element names, and join them together. So:

var names = element.AncestorsAndSelf()
                   .Reverse()
                   .Skip(1) // Skip the root
                   .Select(x => x.Name);
var joined = string.Join(".", names);

Complete program:

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var element = doc.Descendants("watchVideo").First();
        var names = element.AncestorsAndSelf()
                   .Reverse()
                   .Skip(1) // Skip the root
                   .Select(x => x.Name);
        var joined = string.Join(".", names);
        Console.WriteLine(joined);
    }
}

Output:

heroBanner.landing.copies.watchVideo

Note that I haven't lower-cased it, but I assume you can do that if you really want to.

people

See more on this question at Stackoverflow