【问题标题】:C# HtmlAgilityPack adding tbodyC# HtmlAgilityPack 添加 tbody
【发布时间】:2016-04-27 23:50:43
【问题描述】:

C# HtmlAgilityPack,在 LoadHtml 函数之后将 tbody 元素添加到表格中的 DOM 树中,即使它在原始 HTML 文档中不存在。如何禁用此功能?

我的算法创建了一些 XPATH 表达式,通过遍历 dom 树和原始文档中不存在的 tbody 元素使 SelectNodes 找不到所需的项目。我花了很多时间才弄清楚这个:|

是否可以让 SelectNodes 也考虑 HtmlAgilityPack 添加的节点?

例子:

<table>
    <tr><td>data</td></tr>
</table>

我的应用程序会生成这个 XPATH 来提取“数据”: //table/tbody/tr/td

表达式中的 tbody 标记被添加是因为它在 HtmlAgilityPack 解析 html 代码后在 DOM 树中,因为 HtmlAgilityPack 将其添加,即使它不存在。 正因为如此

doc.DocumentNode.SelectNodes("//table/tbody/tr/td");

会失败。

换句话说,tr 元素 (HtmlElement) 的父 TagName 等于 'TBODY' 而不是 'TABLE'。此外,我正在解析许多不同的网站,所以这是一种情况。

SelectNodes 在原始 HTML 代码中搜索,而不是在 HtmlDocument.LoadHtml 之后的 DOM 树中搜索,或者它不考虑由它添加的“虚拟”元素。

【问题讨论】:

  • 我认为您只需将tr/d 更改为tr/td

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


【解决方案1】:

您不必使用完整的层次结构。

如果您想要的只是tds,请使用以下内容:

doc.DocumentNode.SelectNodes("//table//td");

或者只是忽略tbody 节点并获取您关心的所有层次结构:

doc.DocumentNode.SelectNodes("//table//tr/td");

【讨论】:

  • 这只是一种解决方法,该算法在创建 xpath 表达式时必须处理许多其他情况,它不适合我的需要。目前我只是从表达式中删除 tbody 标签,但这也是一个坏主意,因为当我解析其他网站时,有些网站确实有那个 tbody 标签。此外,HtmlAgilityPack 可能会将其他元素(如 tbody)添加到 DOM 树中,即使它们不存在。
  • 这不是一种解决方法。这就是 XPath 的工作方式。在这里查看:w3.org/TR/xpath/#node-tests//table 选择来自根节点的所有 table 元素后代,//td 选择上下文节点的 table 元素子节点的所有 td 元素后代。
  • 我的意思是你的 XPath 代码没问题,但在我的情况下它是解决方法。一个网站有一个没有,谁知道HtmlAgilityPack会在其他网站上添加什么其他元素(我必须向我解析未知的网站)。
猜你喜欢
  • 1970-01-01
  • 2012-09-28
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-10
  • 2020-09-04
相关资源
最近更新 更多