node.Descendants(0)似乎返回所有子節點而不是第一級

.net html-agility-pack

我正在使用HtmlAgilityPack一次遍歷一個文檔樹。但是,調用node.Descendants(0)似乎返回整個節點樹。

注意:我嘗試用我的逐字HTML字符串粘貼,但SE解析器不喜歡它,所以我將其添加為片段。

<html>
    <head>
    <meta name="generator"
    content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
    <title></title>
    </head>
    <body>
    <p id="p1" class="newline">
        <span id="span1" class="bold">
        <span id="span2" class="literal">BOLD TEXT</span>
        </span>
    </p>
    </body>
</html>

var doc = new HtmlAgilityPack.HtmlDocument();

doc.LoadHtml(html);

var lines = doc.DocumentNode.Descendants().Where(x => x.HasClass("newline")).ToArray();

Console.WriteLine(string.Join("\r\n", lines[0].Descendants(0)
    .Select(x => $"{x.Name} {x.Id} {(x as HtmlTextNode)?.Text}")));

以上代碼的作用是獲取第一個p標記的後代。如果我將01作為參數傳遞,它將返回整個節點樹並在下面輸出。問題是包含BOLD TEXT的文本節點嵌套在p標籤的3個級別。使用上面的代碼,我只希望它返回一個文本節點span1 ,然後是另一個文本節點。

我打電話給.Descendants時我做錯了什麼?

#text

span span1
#text

span span2
#text  BOLD TEXT
#text

#text

編輯:臨時解決方法是確保只獲得父級等於當前節點的後代。但仍在尋找更實用的解決方案。

Console.WriteLine(string.Join("\r\n", lines[0].Descendants(0)
    .Where(x => x.ParentNode == lines[0])
    .Select(x => $"{x.Name} {x.Id} {(x as HtmlTextNode)?.Text}")));

熱門答案

我有同樣的問題,開始谷歌搜索,發現你的問題:)。然後我決定直接向開發人員詢問 。以下是答案的簡短版本:

根據代碼,它的行為方式不同:

/// <summary>
/// Gets all Descendant nodes in enumerated list
/// </summary>
/// <returns></returns>
public IEnumerable<HtmlNode> Descendants(int level)
{
    if (level > HtmlDocument.MaxDepthLevel)
    {
        throw new ArgumentException(HtmlNode.DepthLevelExceptionMessage);
    }

    foreach (HtmlNode node in ChildNodes)
    {
        yield return node;

        foreach (HtmlNode descendant in node.Descendants(level + 1))
        {
            yield return descendant;
        }
    }
}

它接受所有後代並通過將級別遞增1來獲取子級,直到不再有後代或達到最大級別(int.MaxValue)。但是,我同意你的觀點,它可能應該返回後代,直到達到指定的級別。不幸的是,為了向後兼容,我們可能不會對此方法做任何不影響當前應用程序的任何操作。

但是,在您的情況下,可以使用ChildNodes而不是Descendants(0) 。代碼如下所示:

    Console.WriteLine(string.Join("\r\n", lines[0].ChildNodes
                            .Select(x => $"{x.Name} {x.Id} {(x as HtmlTextNode)?.Text}")));


許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因