J'ai la mise en page HTML actuelle
<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>
J'essaie d'obtenir les données à l'intérieur de //table[1]//table[2]
, mais je continue à obtenir un HtmlNode nul ( System.NullReferenceException
) pour les éléments suivants:
ne fonctionne pas: doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr//td//table[2]//tbody//tr");
,
Je ne sais pas pourquoi cela se produit car lorsque j'essaie d'obtenir des données pour //table[1]//table[1]
cela fonctionne parfaitement avec cette syntaxe
travaux: doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr//td//table[1]//tbody//tr");
Est-ce que je comprends mal comment fonctionne l'indexation avec Html Agility Pack?
//table[2]
renvoie le 2e élément <table>
dans le même parent car dans XPath:
Le (
[]
) a une priorité plus élevée que (//
et/
). [ Pour référence ]
Dans votre cas, il n'y a qu'un seul <table>
dans chaque <td>
. Par conséquent, l'expression Xpath n'a renvoyé rien. Une solution possible consiste à mettre des parenthèses pour modifier la priorité:
(//table[2]//tbody//tr//td//table)[2]//tbody//tr
Au-dessus de Xpath, obtenez le deuxième élément <table>
de tous les <table>
renvoyés par le XPath //table[2]//tbody//tr//td//table
intérieur //table[2]//tbody//tr//td//table
. Ensuite, à partir de cette <table>
, continuez à renvoyer les éléments descendants //tbody//tr
.
J'ai fini par fonder ce hors de tr
« s ne sais pas pourquoi mon autre façon ne fonctionnait pas, mais cette façon fonctionne.
J'ai essentiellement déplacé mon indexation au niveau supérieur à celui de ma table. Ainsi, dans le premier tbody
chaque tableau est ensuite tbody
dans une instruction tr / td et j’ai simplement construit mon HtmlNode pour l’indexation à partir des tr
. Peut-être que Agility Pack fonctionnera mieux si vous élargissez le processus de sélection? IDK.
Quoi qu'il en soit ...
Pour table[2]//table[1]
j'ai utilisé:
HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr[2]//table");
foreach (var cell in table.SelectNodes(".//tr//td/p"))
...
J'ai sélectionné tr [2] comme j'avais un tr / td auparavant avec un espace vide si vous notez l'exemple HTML ci-dessus
Pour table[2]//table[2]
j'ai utilisé
HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr[3]//table[1]");
foreach (var cell in table.SelectNodes(".//tr//td"))
...
Si vous rencontrez des problèmes, essayez de déplacer votre recherche vers une sélection plus large en transmettant des balises spécifiques à des balises plus larges.