使用Html敏捷包选择节点时出现问题
本文关键字:节点 问题 选择 Html 包选择 使用 | 更新日期: 2023-09-27 18:25:32
我有当前的HTML布局
<table> //table[1]
</table>
<table> //table[2]
<tbody>
<tr>
<td>
<p>
</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敏捷包的索引工作原理?
//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"))
...
对于任何有问题的人,试着通过将特定标签推送到更广泛的标签来将搜索范围扩大。