【问题标题】:HtmlAgilityPack | Wrongly retrieved table nodesHtmlAgilityPack |错误检索的表节点
【发布时间】:2012-01-24 21:25:38
【问题描述】:

您好,我刚刚在这个网站上注册了,因为我需要一些帮助。

我想从 nyaa.eu 网站获取结果。

基本上:

  • 表节点被称为<table class="tlist">
  • 每个行节点都称为<tr class="tlistrow">,有时也称为'trusted tlistrow'等。
  • 我尝试检索的节点是:<td class="tlistname"> <td class="tlistsize"> <td class="tlistsn"> and <td class="tlistln">

首先我要检索一个包含所有种子信息的表格:

HtmlNode hnTable = doc.DocumentNode.SelectSingleNode("//table[@class='tlist']");

所以,接下来就是检索其类属性中包含“tlistrow”的所有行:

HtmlNodeCollection hncRows = hnTable.SelectNodes("//tr[contains(@class,'tlistrow')]");

最后的问题是,当我读取每个节点时,它总是相同的:

foreach (HtmlNode row in hncRows)
{
    foreach (HtmlNode child in row.ChildNodes)
    {
        if (child.SelectSingleNode("//td[@class='tlistname']") != null)
        {
            MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("//td[@class='tlistname']").InnerText);
            break;
        }
    }
}

messagebox中显示的文字总是一样的,看起来只是多次选择一个节点。

我该如何解决这个问题,或者如果我做错了什么,请纠正我。

【问题讨论】:

    标签: c# html xpath html-agility-pack nodes


    【解决方案1】:
        foreach (HtmlNode child in row.ChildNodes)
        {
            if (child.SelectSingleNode("//td[@class='tlistname']") != null)
            {
                MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("//td[@class='tlistname']").InnerText);
                break;
            }
        }
    

    您需要了解 相对 XPath表达式和 绝对 XPath表达式之间的区别强>。

    相对 XPath 表达式在 XML 文档中的特定节点(作为初始上下文节点)进行评估。

    针对整个 XML 文档(将文档节点作为初始上下文节点)评估绝对 XPath 表达式。

    任何以字符 / 开头的 XPath 表达式都是绝对 XPath 表达式。

    根据所提供的代码,您希望使用具有初始上下文节点的相对 XPath 表达式,该节点包含在名为 child 的变量中。

    问题在于您使用的表达式:

    //td[@class='tlistname'] 
    

    / 开头,因此是一个绝对的XPath 表达式。

    这个,传递给SelectSingleNode()方法总是选择整个XML文档中的第一个td元素,它有一个class属性和字符串值"tlistname."

    解决方案:使用相对的 XPath 表达式,例如:

    .//td[@class='tlistname'] 
    

    【讨论】:

    • 是的,这是我见过的最简单的修复方法。太感谢了!实际上我从来没有读过 XPath,所以这就是我失败的原因......
    • @KonradPiesiak:不客气。 XPath 是一种最神奇、最强大和最优雅的语言(这些品质在 2.0 和 3.0 版本中得到了提升)。它值得系统学习。
    【解决方案2】:

    表达式中的// XPath 将在文档中的任何位置查找匹配项。不需要时将其删除。

    所以,试试这样的:

    HtmlNode hnTable = doc.DocumentNode.SelectSingleNode("//table[@class='tlist']"); 
    HtmlNodeCollection hncRows = hnTable.SelectNodes("/tr[contains(@class,'tlistrow')]");
    foreach (HtmlNode row in hncRows)
    {
        foreach (HtmlNode child in row.ChildNodes)
        {
            if (child.SelectSingleNode("/td[@class='tlistname']") != null)
            {
                MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("/td[@class='tlistname']").InnerText);
                break;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多