这段树遍历代码的错误在哪里?

2023-12-19

有一个错误Traverse()这导致它多次迭代节点。

被窃听的代码

public IEnumerable<HtmlNode> Traverse()
{
    foreach (var node in _context)
    {
        yield return node;
        foreach (var child in Children().Traverse())
            yield return child;
    }
}

public SharpQuery Children()
{
    return new SharpQuery(_context.SelectMany(n => n.ChildNodes).Where(n => n.NodeType == HtmlNodeType.Element), this);
}

public SharpQuery(IEnumerable<HtmlNode> nodes, SharpQuery previous = null)
{
    if (nodes == null) throw new ArgumentNullException("nodes");
    _previous = previous;
    _context = new List<HtmlNode>(nodes);
}

测试代码

    static void Main(string[] args)
    {
        var sq = new SharpQuery(@"
<a>
    <b>
        <c/>
        <d/>
        <e/>
        <f>
            <g/>
            <h/>
            <i/>
        </f>
    </b>
</a>");
        var nodes = sq.Traverse();
        Console.WriteLine("{0} nodes: {1}", nodes.Count(), string.Join(",", nodes.Select(n => n.Name)));
        Console.ReadLine();

Output

19 个节点:#document,a,b,c,g,h,i,d,g,h,i,e,g,h,i,f,g,h,i

预期输出

每个字母 a-i 打印一次。

似乎无法弄清楚哪里出了问题......node.ChildNodes does返回的只是直接子项吧? (来自 HtmlAgilityPack)


如果您想自己尝试运行,请参加完整课程(精简版)。

public class SQLite
{
    private readonly List<HtmlNode> _context = new List<HtmlNode>();
    private readonly SQLite _previous = null;

    public SQLite(string html)
    {
        var doc = new HtmlDocument();
        doc.LoadHtml(html);
        _context.Add(doc.DocumentNode);
    }

    public SQLite(IEnumerable<HtmlNode> nodes, SQLite previous = null)
    {
        if (nodes == null) throw new ArgumentNullException("nodes");
        _previous = previous;
        _context = new List<HtmlNode>(nodes);
    }

    public IEnumerable<HtmlNode> Traverse()
    {
        foreach (var node in _context)
        {
            yield return node;
            foreach (var child in Children().Traverse())
                yield return child;
        }
    }

    public SQLite Children()
    {
        return new SQLite(_context.SelectMany(n => n.ChildNodes).Where(n => n.NodeType == HtmlNodeType.Element), this);
    }
}

首先,请注意,只要我们迭代没有任何同级的元素,一切都会按计划进行。一旦我们点击元素<c>,事情开始变得混乱。同样有趣的是<c>, <d> and <e>都认为它们含有<f>的孩子们。

让我们仔细看看您的电话SelectMany():

_context.SelectMany(n => n.ChildNodes)

迭代中的项目_context and 积累每个项目的子节点。我们来看看_context。一切都应该没问题,因为它是List长度1。或者是吗?

我怀疑你的SharpQuery(string)构造函数将同级元素存储在同一列表中。在这种情况下,_context可能长度不长1不再,记住,SelectMany() 积累列表中每个项目的子节点。

例如,如果_context是一个列表,其中包含<c>, <d>, <e> and <f>, only <f>有孩子,并且SelectMany()对每个元素调用一次,它将累积并返回<f>四次。

我认为这是你的错误。

EDIT:既然你已经发布了完整的课程,我就不必再猜测了。看看迭代时的操作顺序<b>(为了更好的理解,用列表替换迭代器):

  1. Call Children() on <b>,返回<c>, <d>, <e> and <f>,
  2. Call Traverse() on the resulting list:
    1. Call Children() on <c>, but _context实际上包含<c>, <d>, <e> and <f>, 不仅<c>,这样就返回<g>, <h> and <i>,
    2. Call Children() on <d>,同样的事情,因为_context is the same for both <c> and <d> (and <e>, and <f>),
    3. 起泡沫,冲洗,重复。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这段树遍历代码的错误在哪里? 的相关文章

  • UTF8/UTF16 和 Base64 在编码方面有什么区别

    In c 我们可以使用下面的类来进行编码 System Text Encoding UTF8 System Text Encoding UTF16 System Text Encoding ASCII 为什么没有System Text En
  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • 模板类的不明确多重继承

    我有一个真实的情况 可以总结为以下示例 template lt typename ListenerType gt struct Notifier void add listener ListenerType struct TimeListe
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • 为什么禁止在 constexpr 函数中使用 goto?

    C 14 对你能做什么和不能做什么有规则constexpr功能 其中一些 没有asm 没有静态变量 看起来相当合理 但标准也不允许goto in constexpr功能 即使它允许其他控制流机制 这种区别背后的原因是什么 我以为我们已经过去
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 像“1$”这样的位置参数如何与 printf() 一起使用?

    By man I find printf d width num and printf 2 1 d width num 是等价的 但在我看来 第二种风格应该与以下相同 printf d num width 然而通过测试似乎man是对的 为什
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 使用 plyr、doMC 和 summarise() 处理非常大的数据集?

    我有一个相当大的数据集 约 140 万行 我正在对其进行一些拆分和总结 整个事情需要一段时间才能运行 而我的最终应用程序依赖于频 繁运行 所以我的想法是使用doMC和 parallel TRUE像这样使用 plyr 进行标记 稍微简化一下
  • 在序言中的特定元素之前和之后拆分列表(不使用“split”谓词?)

    我试图将列表拆分为特定元素 特别是 停止 一词 之前的项目以及该元素之后的项目 我知道你可以使用 split 来做到这一点 但我是序言新手 所以我正在尝试在当前不使用这些函数的情况下操作事物 所以我真的很想知道这是否可能 也许还有一些正确方
  • 设计键盘快捷键的最佳实践

    I am a big fan of keyboard shortcuts If some function or operation doesn t have shortcut I tend to write a little progra
  • 如何动态创建类

    我需要动态创建一个类对象 我尝试使用动态关键字 dynamic dataTransferObject new dtoClass dataTransferObject Property1 someValue dataTransferObjec
  • Python - IndexError:列表索引超出范围 - 不起作用

    这是我的 scrap py 代码 from bs4 import BeautifulSoup as soup from urllib request import urlopen as uReq website https houston
  • 圆圈的边框样式为刻度线

    我有一个带有虚线边框的圆圈 然而 边框应该更像垂直的破折号 而不是点 有没有办法用css使边框与设计完全相同 垂直虚线而不是粗实线 我想更改此类 OtherCaptionBorder My css caption circle positi
  • 使用 JsonConverter 的 Json.NET 自定义序列化 - 如何获得“默认”行为

    我的类 DataType 有一个 JsonConverter 当 Json 中使用纯字符串作为 DataType 类型的属性值时 我想进行一些特殊处理 在该值是 完整 对象的情况下 我想进行 正常 反序列化 这是我的尝试 public ov
  • print() 函数打印列表中每个元素的内容

    基本上 我正在尝试编写一个打印语句 该语句允许我在运行 driver java 时将每行的元素作为 println 打印为输出 我一生都不知道该怎么做 任何帮助将不胜感激 这是driver java public class Driver
  • 如何将 ANSEL 文本转换为 UTF-8

    如何在 C 中将 ANSEL 编码的文本更改为 UTF 8 这是一个重要的转换 因为 Windows NET Framework 没有 ANSEL 代码页 看here http www heiner eichmann de gedcom c
  • 实体框架登录失败错误

    我已经在 IIS 中托管了我的 WCF 应用程序 并设置了一个集成了 4 0 的应用程序池 我将池标识配置为网络服务 我已经检查了与此问题相关的其他帖子 但无法解决它 我得到以下异常 System Data Entity Core Enti
  • 混合地图类型图块的 Google 地图图块 URL?

    我找到了常规地图图块的基本 URL 结构 https mts1 google com vt lyrs m 186112443 hl x local src app x 1325 y 3143 z 13 s Galile 从 Google 获
  • SetProcessDpiAwareness 没有效果

    我一直在尝试禁用 ClickOnce 应用程序上的 DPI 感知 我很快发现 不可能在清单中指定它 因为 ClickOnce 不支持清单文件中的 asm v3 我发现的下一个选项是调用新的 Windows 函数设置进程Dpi感知 https
  • 为什么建议的 Swift 单例实现使用结构体?

    The 普遍接受的 Swift 单例模式 https stackoverflow com a 24024762 998117在类变量 类型属性中使用 Struct 代替 class MySingleton class var sharedI
  • 如何在opencart中自动选择结账选项?

    在我正在开发的商店中 用户只有创建帐户才能查看价格并将产品添加到购物车 之后 他们可以将产品添加到购物车 帐单详细信息和交付详细信息选项将自动填写用户的地址 送货方式免费 付款方式为 货到付款 我如何自动选择这些选项并隐藏它们 这样剩下的唯
  • 如何在 Keras 中使用 categorical_hinge?

    也许是一个非常愚蠢的问题 但我找不到如何在 Keras 中使用 categorical hinge 的示例 我进行分类 我的目标是shape 1 值为 1 0 1 所以我有 3 个类别 使用函数式 API 我设置了输出层 如下所示 输出 密
  • C# FluentScheduler 作业不重复

    我有一个简单的任务 我试图使用 FluentScheduler 重复执行 但我似乎无法让它正常运行 我对 工作 和 行动 完全陌生 所以我确信这是我没有考虑到的愚蠢的事情 我正在修改我原来的问题 因为提供的解决方案适用于控制台应用程序 但不
  • matlab中循环与矢量化的比较

    让我们考虑以下脉冲函数代码 function y impulse function n y 0 if n 0 y 1 end end 这段代码 gt gt n 2 2 gt gt i 1 length n gt gt f i impulse
  • 每次我打开对话框时,Microsoft Visual Studio 2019“服务器繁忙”。 Devenv.exe 与 textservice.dll 发生错误

    每次我打开对话框时 Microsoft Visual Studio 2019 都会显示 服务器繁忙 对话框 Procmon 搜索 devenv exe 发现以下文件至少有 100 个 NO SUCH FILE 条目 C Users jlav
  • 从字符串中删除重音字符 - Python

    我从网页获取一些数据并在 python 中像这样读取它 origional doc urllib2 urlopen url read 有时此网址包含以下字符 and and ect 我怎样才能从字符串中删除这些字符 现在这就是我正在尝试的
  • 这段树遍历代码的错误在哪里?

    有一个错误Traverse 这导致它多次迭代节点 被窃听的代码 public IEnumerable