代码之家  ›  专栏  ›  技术社区  ›  Jeson Martajaya

HtmlAgilityPack-为子体选择SingleNode

  •  0
  • Jeson Martajaya  · 技术社区  · 6 年前

    我发现HtmlAgilityPack SelectSingleNode 始终从原始DOM的第一个节点开始。是否有等效的方法来设置其起始节点?

    示例html

    <html>
      <body>
        <a href="https://home.com">Home</a>
        <div id="contentDiv">
        <tr class="blueRow">
            <td scope="row"><a href="https://iwantthis.com">target</a></td>
        </tr>
        </div>
      </body>
    </html>
    

    非工作代码

    //Expected:iwantthis.com  Actual:home.com, 
    string url = contentDiv.SelectSingleNode("//tr[@class='blueRow']")
                           .SelectSingleNode("//a") //What should this be ?
                           .GetAttributeValue("href", "");
    

    我必须用以下代码替换上面的代码:

        var tds = contentDiv.SelectSingleNode("//tr[@class='blueRow']").Descendants("td");
        string url = "";
        foreach (HtmlNode td in tds)
        {
            if (td.Descendants("a").Any())
            {
                url= td.ChildNodes.First().GetAttributeValue("href", "");
            }
        }
    

    我正在上使用HtmlAgilityPack 1.7.4。Net Framework 4.6.2

    1 回复  |  直到 6 年前
        1
  •  4
  •   Developer Guy Adam    6 年前

    您使用的XPath总是从文档的根开始。 SelectSingleNode("//a") 表示从文档的根开始查找第一个 a 文件中的任何地方;这就是为什么它抓住了主链接。

    如果要从当前节点开始,应使用 . 选择器。 SelectSingleNode(".//a") 意味着找到第一个 A. 位于当前节点下方的任何位置。

    因此,您的代码如下所示:

    string url = contentDiv.SelectSingleNode(".//tr[@class='blueRow']")
                       .SelectSingleNode(".//a")
                       .GetAttributeValue("href", "");