C# 计算XML文档中的父节点数
我试图统计XML文档中的所有父节点。我见过像C# 计算XML文档中的父节点数,c#,xml,count,parent,C#,Xml,Count,Parent,我试图统计XML文档中的所有父节点。我见过像.SelectNodes(“general/parent”).Count这样的解决方案,但这是一个固定的解决方案。问题是我必须使用生成的XML文档来完成这项工作。所以我不知道XML结构 我创造了一个例子。假设生成了以下文档,而根本不知道任何标记名或信息: <?xml version="1.0" encoding="UTF-8"?> <general> <settings> <resolu
.SelectNodes(“general/parent”).Count这样的解决方案,但这是一个固定的解决方案。问题是我必须使用生成的XML文档来完成这项工作。所以我不知道XML结构
我创造了一个例子。假设生成了以下文档,而根本不知道任何标记名或信息:
<?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>
1920x1080
1
上下快速移动
41
亚历克斯
25
我想看一下这份文件,结果是:5。因为文档有5个“父项”(常规、设置、数据、人员和人员)。但这不包括“分辨率”、“版本”、“姓名”和“年龄”,因为他们没有孩子(没有父母)。但是,请再次记住,文档是生成的
我希望这个问题足够清楚。有没有办法做到这一点?使用LinqToXml,您可以执行以下操作:
XDocument.Parse(@"...").Descendants().Where(n => n.Elements().Any()).Select(n => n.Name).Distinct().Count();
你需要一个递归算法,就像这个
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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Xml.Linq;
命名空间GetMaxXMLDepth
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串doc=@“
1920x1080
1
上下快速移动
41
亚历克斯
25
";
var xd=XDocument.Parse(doc);
int maxDepth=GetMaxChildDepth(xd.Root);
}
静态int GetMaxChildDepth(XElement元素)
{
int结果=1;
//始终返回1,因为根节点的深度为1。
//此外,返回此方法调用所有子级时返回的最大深度。
if(element.HasElements)
结果+=element.Elements().Max(p=>GetMaxChildDepth(p));
返回结果;
}
}
}
通常我会说使用“/*[count(*)>0]”,但您必须处理循环中的distinct。(即,此人出现两次,因为他们都是父母)感谢您的回复,我非常感谢!我对XDocument不是很熟悉。您能举例说明如何从OpenFileDialog加载XML文档吗?@guidoviser静态方法XDocument.load
将采用流或文件路径。OpenFileDialog.OpenFile()返回一个流
。我试着回答。它几乎起作用了!:D但is也将最后一个标记视为“父”标记,例如Alex,可能是因为它将InnerText视为子标记?只有在标记下有标记时,它才需要算作父标记。有没有办法做到这一点?我非常感谢迄今为止的帮助@Guidoviser我不完全确定它是否满足您的要求。该算法计算文档中嵌套最多的子元素的深度,而不是包含子元素的元素数。碰巧在示例文档中这两个都是5。有趣的是,我也需要这个^^解决方案就是取数字,取1。我用各种XML文档对它进行了测试,这似乎就达到了目的。谢谢你的帮助!但正如你所说,这不是这个问题的真正答案,所以我不能接受你在这个问题上的答案。如果我使用这个解决方案。最终结果是:System.Linq.Enumerable+d_81`1[System.Xml.Linq.XName]而不是数字。我做错什么了吗?这是符合您描述的节点名称集合。在末尾添加.Count()以计算节点数。我用这个更新了答案。
int count = ParentNode.SelectNodes(ChildNodesXPath).Count;