【问题标题】:Select HTML from specific position using Html Agility Pack使用 Html Agility Pack 从特定位置选择 HTML
【发布时间】:2013-02-03 05:12:43
【问题描述】:

我需要从第 64 行第 45 行到第 183 行第 22 行获取 html 文本节点。我对 XPath 很陌生,我不太确定我的选择是什么。我应该如何进行? 我想到了这样的事情:

var nodes=doc.DocumentNode.SelectNodes("//text()[position() > startPosition and position() < endPosition]");

【问题讨论】:

  • 为什么需要为此使用 HTML Agility 包?只需使用标准字符串操作,然后解析生成的字符串。
  • @Justin 当你得到结果字符串时,你可能会得到类似some text&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;h1&gt;heading&lt;/h1&gt; 的东西,我认为解析它可能比你做相反的事情更难:解析 HTML ,然后过滤你需要的。

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


【解决方案1】:

XPath 无法做到这一点:它对 XML 中的行号和字符位置一无所知。

position() 函数返回节点在节点列表中的相对位置 - 例如列表中的第一个节点返回 1,第二个节点返回 2,依此类推。

要获取行位置信息,您可以使用XElementXmlReader 解析XML,然后使用IXmlLineInfo 接口。

请注意,虽然使用行/字符位置来识别 XML 文件的片段是有问题的:XML 处理器通常会重新格式化 XML,添加/删除空格和结束行,因此相同的 XML 片段可以改变位置。

【讨论】:

  • 那么我可以用什么来代替 XPath?我唯一想到的是将整个 html 解析为字符串。之后我需要手动完成其余的工作......
  • @Xardas:我用一些建议扩展了我的答案。
【解决方案2】:

HtmlNode 类有两个重要的属性(对于你需要做的):

  • Line(节点开始的那一行)
  • LinePosition(节点结束的那一行)

你可以这样做:

var nodes = doc.DocumentNode.Descendants("#text").Where(
    x => (x.Line > 64 || (x.Line == 64 && x.LinePosition >= 45)) &&
         (x.Line < 183 || (x.Line == 183 && x.LinePosition <= 22))
);

当然,你也可以doc.DocumentNode.SelectNodes("//text()").Where(...)

您必须处理的一个问题:

它不会告诉您节点在哪里结束,因此上述解决方案可能会为您提供以大于183 的行结束的节点,或者在183 行但位置大于22 的节点。为此,您可以使用节点的OuterHtml 属性,并进行一些字符串操作(获取长度以了解其结束位置,通过\n 拆分以了解行数等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多