【问题标题】:Count parent nodes in XML Document计算 XML 文档中的父节点
【发布时间】:2013-10-31 15:55:59
【问题描述】:

我正在尝试计算 XML 文档中的所有父节点。我见过像.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> 

我想浏览此文档并得到以下结果: 5. 由于该文档有 5 个“父级”(常规、设置、数据、人员和人员)。但它不包括“分辨率”、“版本”、“名称”和“年龄”,因为它们没有孩子(没有父母)。但再一次记住,文档是生成的!

我希望这个问题足够清楚。有没有办法做到这一点?

【问题讨论】:

  • 通常我会说使用 "//*[count(*)>0]",但你必须在循环中处理 distinct。 (即 Person 出现两次,因为他们都是父母)

标签: c# xml count parent


【解决方案1】:

使用 LinqToXml,您可以执行以下操作:

XDocument.Parse(@"...").Descendants().Where(n => n.Elements().Any()).Select(n => n.Name).Distinct().Count();

【讨论】:

  • 如果我使用这个解决方案。最终结果是:System.Linq.Enumerable+d_81`1[System.Xml.Linq.XName] 而不是数字。我做错了吗?
  • 它是与您的描述相匹配的节点名称的集合。在末尾添加 .Count() 以计算节点数。我用那个更新了答案。
【解决方案2】:

你需要一个递归算法,比如这个;

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;
        }
    }
}

【讨论】:

  • 感谢您的回复,不胜感激!我对 XDocument 不是很熟悉。你能举个例子说明如何从 OpenFileDialog 加载 XML 文档吗?
  • @GuidoVisser 静态方法XDocument.Load 将采用Stream 或文件路径。 OpenFileDialog.OpenFile() 返回一个Streammsdn.microsoft.com/en-us/library/…
  • 我尝试了答案。它几乎可以工作! :D 但也将最后一个标签视为“父”前。 &lt;name&gt;Alex&lt;/name&gt; 可能是因为它把 InnerText 视为一个孩子?仅当标签下有标签时,它才需要算作父级。有没有办法做到这一点?到目前为止,我感谢您的帮助!
  • @GuidoVisser 我不完全确定它是否满足您的要求。该算法计算文档中嵌套最多的子元素的深度,而不是具有子元素的元素数。恰好在示例文档中两者都是 5。
  • 有趣的是我也需要这个 ^^ 解决方法就是取数字并减1。我用各种 XML 文档对其进行了测试,这似乎可以解决问题。谢谢你的帮助!但正如你所说,这不是这个问题的真正答案,所以我不能接受你在这个帖子上的回答。
【解决方案3】:
int count = ParentNode.SelectNodes(ChildNodesXPath).Count;                    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多