1

我正在尝试在 HTML 文档中查找表,其中前 2 行包含 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 列在前 2 行中有文本。这就是我想要匹配的。

4

1 回答 1

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

这个 XPath 表达式有很多问题

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

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

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

  4. //*[contains(text(), *)]这将选择其第一个文本节点子节点包含第一个元素子节点的字符串值的任何元素——但您只是想验证 atd是否具有后代文本子节点——这可以通过以下方式正确选择: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()]
  ]
于 2012-08-12T21:59:59.947 回答