使用Html敏捷包选择节点时出现问题

本文关键字:节点 问题 选择 Html 包选择 使用 | 更新日期: 2023-09-27 18:25:32

我有当前的HTML布局

<table> //table[1]
</table>
<table> //table[2]
<tbody>
   <tr>
      <td>
         <p>
            &nbsp;
         </p>
      </td>
   </tr>
   <tr>
      <td>
         <table> //table[1]//table[1]
            <tbody>
               <tr>
                  <td>
                     <p>
                        INFO 1
                     </p>
                  </td>
                  <td>
                     <p>
                        INFO 2
                     </p>
                  </td>
                  <td>
                     <p>
                        INFO 3
                     </p>
                  </td>
                  <td>
                     <p>
                        INFO 4
                     </p>
                  </td>
               </tr>
            </tbody>
         </table>
      </td>
   </tr>
   <tr>
      <td>
         <table> //table[1]//table[2]
            <tbody>
               <tr>
                  <td>
                     <p><strong>Name</strong></p>
                  </td>
                  <td>
                     <p><strong>Quantity</strong></p>
                  </td>
               </tr>
               <tr>
                  <td>
                     <p>Apples </p>
                  </td>
                  <td>10</td>
               </tr>
            </tbody>
         </table>
      </td>
   </tr>
   <tr>
      <td>
         <table>  //table[1]//table[3]
         </table>
      </td>
   </tr>
</tbody>
</table>

我正在尝试获取//table[1]//table[2]中的数据,但我一直为以下内容获取空HtmlNode(System.NullReferenceException):

不起作用:doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr//td//table[2]//tbody//tr");

我不确定为什么会发生这种情况,因为当我尝试为//table[1]//table[1]获取数据时,它与此语法配合得很好

作品:doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr//td//table[1]//tbody//tr");

我是否误解了Html敏捷包的索引工作原理?

使用Html敏捷包选择节点时出现问题

//table[2]返回同一父级中的第二个<table>元素,因为在XPath:中

[])具有比(///)更高的优先级(优先级)。【参考】

在您的情况下,每个<td>中只有一个<table>,因此Xpath表达式不返回任何内容。一种可能的解决方案是放括号来改变优先级:

(//table[2]//tbody//tr//td//table)[2]//tbody//tr

上面的Xpath从内部Xpath //table[2]//tbody//tr//td//table返回的所有<table>中获得第二个<table>元素。然后从那个<table>,继续返回子代//tbody//tr元素。

我最终不得不以tr为基础。我不确定为什么我的另一种方式不起作用,但这种方式确实起作用。

我基本上把索引移到了表上的下一个级别。因此,在第一个tbody中,此后的每个表都在一个tr/td语句中,我只是简单地构建了我的HtmlNode来索引tr的s。如果你扩大选择过程,也许敏捷包效果更好?IDK。

无论如何。。。

对于我使用的table[2]//table[1]

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr[2]//table");
foreach (var cell in table.SelectNodes(".//tr//td/p"))
...

I选择tr[2],因为如果您注意到上面的示例HTML,我之前有一个带有空格的tr/td

对于table[2]//table[2],我使用

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr[3]//table[1]");
foreach (var cell in table.SelectNodes(".//tr//td"))
...

对于任何有问题的人,试着通过将特定标签推送到更广泛的标签来将搜索范围扩大。