【问题标题】:"Expression must evaluate to a node-set" when trying to select a HTML node尝试选择 HTML 节点时,“表达式必须评估为节点集”
【发布时间】:2019-02-07 19:49:52
【问题描述】:

我正在尝试使用 HtmlAgilityPack 获取 HTML 文件的特定部分。

输入 HTML 文件(简化和清理):

<html>
<head>
</head>
<body>
    <section>
        <div>
        </div>
    </section>
    <section>
        <div>
        </div>
        Line 1
        Line 2 - Text here
        Line 3
        <div>
        </div>
    </section>
</body>
</html>

这是我的代码:

Dim getPage As HtmlDocument = webGet.Load(Uri)
Dim AllTextLines As HtmlNodeCollection = getPage.DocumentNode.SelectNodes("/html/body/section[2]/text()")
Dim SecondTextLine As HtmlNodeCollection = getPage.DocumentNode.SelectNodes("/html[1]/body[1]/section[2]/#text[2]")

设置SecondTextLine 的值失败并出现以下错误:

System.Xml.XPath.XPathException:表达式必须计算为节点集

我想得到的是:

  1. 仅包含“Line 2 - Text here”的行
  2. 一个部分中的所有文本都没有子元素(在我的例子中是&lt;div&gt;),但作为一个节点,一个包含所有文本的字符串。

我该怎么做?

编辑: 我再次添加了 XPath 标记,因为返回的错误直接来自 System.Xml.XPath.XPathException,而不是来自 HtmlAgilityPack。

【问题讨论】:

  • 它遵循基本的 xml 架构,因此 xml 序列化可能值得研究
  • 你能澄清一下吗?在项目 1. 中,会导致仅包含 2 而不是 1 或 3 的行的逻辑是什么?在项目 2. 中,您的部分有两个子 &lt;div&gt; 元素,那么您为什么要从该部分中获取任何文本?这似乎与All text within a section without child elements 相矛盾。
  • @djv 回答您的问题。 1。我每天都下载页面,第二行的内容对于判断要采取的进一步行动/页面内容至关重要。如前所述,输入 HMTL 被简化,但结构被保留。 2。这是摘要页面的结构,我对此完全没有影响。

标签: vb.net xpath html-agility-pack


【解决方案1】:

字符串 /html[1]/body[1]/section[2]/#text[2] 不是有效的 XPath 表达式。糟糕的错误消息,但您当然不会期望它选择任何内容。

如果你想要第二个文本节点,那就是/html[1]/body[1]/section[2]/text()[2]。但是,如果您想要文本“第 2 行 - 此处的文本”,那么您不是在选择节点,而是在节点内选择一个字符串,因此 SelectNodes() 是错误的调用方法。您似乎正在使用 XPath 1.0 处理器,因此在 XPath 表达式本身中进行字符串操作将非常困难,通常最简单的方法是将整个节点返回到宿主语言并在那里进行字符串操作。或者切换到 XPath 2.0 处理器,然后您可以使用诸如 tokenize() 之类的函数来分割换行符边界上的文本。

【讨论】:

    猜你喜欢
    • 2013-07-24
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 2020-07-13
    相关资源
    最近更新 更多