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>
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.
See more on this question at Stackoverflow