Query XPath 'HTML Agility Pack' con AND logico

c# html-agility-pack xpath

Domanda

Sto cercando di trovare una tabella in un documento HTML con le prime 2 righe contenenti 3 colonne con testo in.

Ho provato a provare ad usare la seguente query, che voglio restituire al nodo che ha le prime 2 righe della tabella che contiene il testo nella prima colonna:

string xpath = @"//table//table[//tr[1]//td[1]//*[contains(text(), *)] and //tr[2]//td[1]//*[contains(text(), *)]]";
HtmlNode temp = doc.DocumentNode.SelectSingleNode(xpath);

Non funziona correttamente, mon.

Ecco alcuni esempi di HTML, che è la tabella che sto cercando di abbinare:

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

Si noti che le colonne 1,3,5 contengono testo nelle prime 2 righe. Questo è quello che sto cercando di abbinare.

Risposta accettata

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

Ci sono molti problemi con questa espressione XPath :

  1. //table//table seleziona qualsiasi table che sia un discendente di una table . Tuttavia, nel documento XML fornito non ci sono tabelle nidificate.

  2. table[//tr[1]//td[1]//*[contains(text(), *)] . //tr all'interno del predicato è un'espressione Xpath assoluta : seleziona tutti gli elementi tr nell'intero documento , non solo nella sottostruttura radicata da questo elemento table . Molto probabilmente vuoi .//tr invece di //tr .

  3. //td[1] seleziona ogni td elemento che è il primo td figlio del suo genitore - ma molto probabilmente si desidera solo il primo discendente td elemento. In tal caso, è necessario utilizzare questa espressione XPath: (//td)[1]

  4. //*[contains(text(), *)] questo seleziona qualsiasi elemento il cui primo nodo di testo figlio contenga il valore di stringa del primo elemento child - ma si vuole semplicemente verificare che un td abbia un nodo figlio di testo discendente - questo può essere correttamente selezionato con: td[.//text()]

Combinando le correzioni di tutti questi problemi, ciò che vorresti è qualcosa di simile :

  //table
     [(.//tr)[1]/td[1][.//text()]
    and
      (.//tr)[2]/td[1][.//text()]
     ]

In alternativa, si potrebbe scrivere un'espressione equivalente ma più comprensibile e meno soggetta a errori come questa:

//table
  [descendant::tr[1]/td[1][descendant::text()]
 and
   descendant::tr[1]/td[1][descendant::text()]
  ]


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é