Problemi nella selezione dei nodi con Html Agility Pack

c# html html-agility-pack

Domanda

Ho il layout HTML corrente

<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>

Sto cercando di ottenere i dati all'interno di //table[1]//table[2] , ma continuo a ricevere un HtmlNode null ( System.NullReferenceException ) per quanto segue:

does not 'work: doc.DocumentNode.SelectSingleNode("//table[2]//tbody//tr//td//table[2]//tbody//tr"); ,

Non sono sicuro del motivo per cui ciò accade quando provo ad ottenere dati per //table[1]//table[1] funziona perfettamente con questa sintassi

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

Sto fraintendendo il modo in cui l'indicizzazione funziona con Html Agility Pack?

Risposta accettata

//table[2] restituisce il secondo elemento <table> all'interno dello stesso genitore perché in XPath:

Il ( [] ) ha una precedenza (priorità) maggiore di ( // e / ). [ Per riferimento ]

Nel tuo caso, c'è un solo <table> in ogni <td> , quindi l'espressione Xpath non restituiva nulla. Una possibile soluzione è mettere parentesi per alterare la precedenza:

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

Sopra Xpath ottiene il secondo elemento <table> da tutti i <table> s restituiti dalla //table[2]//tbody//tr//td//table interna XPath //table[2]//tbody//tr//td//table . Quindi da quel <table> , continua a restituire discendenti //tbody//tr elementi.


Risposta popolare

Alla fine ho dovuto tr il motivo per cui il mio altro modo non funzionava, ma in questo modo funziona.

Fondamentalmente ho spostato la mia indicizzazione al livello successivo sopra il mio tavolo. Quindi entro il primo tbody ogni tabella successiva è all'interno di un'istruzione tr / td, e ho semplicemente costruito il mio HtmlNode per indicizzare i tr . Forse Agility Pack funziona meglio se allarghi il processo di selezione? IDK.

In ogni modo ...

Per la table[2]//table[1] ho utilizzato:

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

Ho selezionato tr [2] come ho avuto un tr / td prima con uno spazio vuoto se si nota l'esempio HTML sopra

Per la table[2]//table[2] ho usato

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

Per chiunque abbia problemi, prova a spostare la ricerca in una selezione più ampia spingendo tag specifici su quelli più ampi.



Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché