代码之家  ›  专栏  ›  技术社区  ›  Megrez7

当试图选择HTML节点时,“表达式必须计算为节点集”

  •  0
  • Megrez7  · 技术社区  · 6 年前

    我正在尝试使用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. 仅包含“第2行-此处为文本”的行
    2. 节中没有子元素的所有文本( <div> 在我的例子中)但是作为一个节点,一个包含所有文本的字符串。

    我该怎么做?

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Michael Kay    6 年前

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

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