'HTML Agility Pack' XPath-Abfrage mit logischem UND

c# html-agility-pack xpath

Frage

Ich versuche, eine Tabelle in einem HTML-Dokument zu finden, wobei die ersten zwei Zeilen drei Spalten mit Text enthalten.

Ich habe versucht, die folgende Abfrage zu verwenden, die ich den Knoten zurückgeben möchte, der die ersten beiden Zeilen der Tabelle Text in der ersten Spalte enthält:

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

Es funktioniert nicht richtig, Mo.

Hier ist ein Beispiel HTML, das ist die Tabelle, die ich versuche zu entsprechen:

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

Sie bemerken, dass die Spalten 1,3,5 Text in den ersten zwei Zeilen haben. Das versuche ich zu erreichen.

Akzeptierte Antwort

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

Es gibt viele Probleme mit diesem XPath-Ausdruck :

  1. //table//table wählt jede table , die ein Nachkomme einer table . Im bereitgestellten XML-Dokument sind jedoch keine verschachtelten Tabellen vorhanden.

  2. table[//tr[1]//td[1]//*[contains(text(), *)] . Der //tr innerhalb des Prädikats ist ein absoluter Xpath-Ausdruck - er wählt alle tr Elemente im gesamten Dokument aus - nicht nur in dem Teilbaum, der von diesem table verwurzelt ist. Höchstwahrscheinlich willst du .//tr anstelle von //tr .

  3. //td[1] wählt ein beliebiges td Element aus, das das erste td Kind seines Elternteils ist - aber höchstwahrscheinlich möchten Sie nur das erste Nachkommen- td Element haben. Wenn dies der Fall ist, müssen Sie diesen XPath-Ausdruck verwenden: (//td)[1]

  4. //*[contains(text(), *)] Dies wählt ein beliebiges Element aus, dessen erster untergeordneter Textknoten den Zeichenfolgenwert des ersten untergeordneten Elements enthält. Sie möchten jedoch nur überprüfen, ob ein td einen td hat. das kann richtig gewählt werden mit: td[.//text()]

Wenn Sie die Korrekturen all dieser Probleme kombinieren, ist das, was Sie wahrscheinlich wollen, etwas wie :

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

Alternativ könnte man einen äquivalenten, aber verständlicheren und weniger fehleranfälligen Ausdruck schreiben:

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


Related

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow