Reputation: 2299
I am trying to count all the parent nodes in a XML Document. I have seen solutions like .SelectNodes("general/parent").Count
but that is a fixed solution. The problem is that I must do it with a generated XML document. So I don't know the XML structure.
I created an example. Imagine that the following document is generated, without knowing any tag names or information at all:
<?xml version="1.0" encoding="UTF-8"?>
<general>
<settings>
<resolution>1920x1080</resolution>
<version>1.0</version>
</settings>
<data>
<persons>
<person>
<name>Bob</name>
<age>41</age>
</person>
<person>
<name>Alex</name>
<age>25</age>
</person>
</persons>
</data>
</general>
I want to go through this document and have a result of: 5. As the document has 5 "parents" (general, settings, data, persons, and person). But it doesn't count "resolution", "version", "name" and "age" because they have no childs (are no parents). But once again, keep in mind that the document is generated!
I hope this question is clear enough. Is there a way of achieving this?
Upvotes: 0
Views: 1819
Reputation: 2018
With LinqToXml you could do something like:
XDocument.Parse(@"...").Descendants().Where(n => n.Elements().Any()).Select(n => n.Name).Distinct().Count();
Upvotes: 1
Reputation: 14334
You need a recursive algorithm, like this one;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace GetMaxXMLDepth
{
class Program
{
static void Main(string[] args)
{
string doc = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<general>
<settings>
<resolution>1920x1080</resolution>
<version>1.0</version>
</settings>
<data>
<persons>
<person>
<name>Bob</name>
<age>41</age>
</person>
<person>
<name>Alex</name>
<age>25</age>
</person>
</persons>
</data>
</general>";
var xd = XDocument.Parse(doc);
int maxDepth = GetMaxChildDepth(xd.Root);
}
static int GetMaxChildDepth(XElement element)
{
int result = 1;
//always return 1 as the root node has depth of 1.
//in addition, return the maximum depth returned by this method called on all the children.
if (element.HasElements)
result += element.Elements().Max(p => GetMaxChildDepth(p));
return result;
}
}
}
Upvotes: 1