带有逻辑AND的“HTML Agility Pack”XPath查询

c# html-agility-pack xpath

我正在尝试在HTML文档中找到一个表,前两行包含3列文本。

我已经尝试使用以下查询,我想返回表格的前2行包含第一列中的文本的节点:

string xpath = @"//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]";
HtmlNode temp = doc.DocumentNode.SelectSingleNode(xpath);

周一,它无法正常工作。

这是一些示例HTML,这是我想要匹配的表:

    <table width="100%" cellpadding="0" border="0">
       <tbody>
       <tr>
          <td width="27%" valign="center"><b><font size="1" face="Helvetica">SOME TEXT<br></font></b></td>
          <td width="1%"></td>
          <td width="9%" valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td width="1%"></td>
          <td width="25%" valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td width="37%"></td>
       </tr>
       <tr>
          <td valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td></td>
          <td valign="center"><font size="1" face="Helvetica">1<br></font></td>
          <td></td>
          <td valign="center"><font size="1" face="Helvetica">SOME TEXT<br></font></td>
          <td></td>
       </tr>
       </tbody>
</table>

您注意到列1,3,5在前两行中有文本。这就是我想要匹配的东西。

一般承认的答案

//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]

此XPath表达式存在许多问题

  1. //table//table选择任何作为table后代的table 。但是,在提供的XML文档中没有嵌套表。

  2. table[//tr[1]//td[1]//*[contains(text(), *)] 。谓词中的//tr是一个绝对的 Xpath表达式 - 它选择整个文档中的所有tr元素 - 不仅仅是在这个table元素为根的子树中。你很可能想要.//tr而不是//tr

  3. //td[1]选择任何作为其父级的第一个td子元素的td元素 - 但很可能只需要第一个后代td元素。如果是这样,您需要使用此XPath表达式: (//td)[1]

  4. //*[contains(text(), *)]这将选择其第一个文本节点子节点包含第一个元素子节点的字符串值的任何元素 - 但您只想验证td是否具有后代文本子节点 -这可以正确选择: td[.//text()]

结合所有这些问题的更正,您可能想要的是

  //table
     [(.//tr)[1]/td[1][.//text()]
    and
      (.//tr)[2]/td[1][.//text()]
     ]

或者,可以编写一个等效但更容易理解且不易出错的表达式,如下所示:

//table
  [descendant::tr[1]/td[1][descendant::text()]
 and
   descendant::tr[1]/td[1][descendant::text()]
  ]


Related

许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow