So wählen Sie das folgende Geschwister- / XML-Tag mit xpath aus

102

Ich habe eine HTML-Datei (von Newegg) und ihr HTML ist wie folgt organisiert. Alle Daten in ihrer Spezifikationstabelle sind " desc ", während die Titel der einzelnen Abschnitte in " name" stehen. 'Nachfolgend finden Sie zwei Beispiele für Daten von Newegg-Seiten.

<tr>
    <td class="name">Brand</td>
    <td class="desc">Intel</td>
</tr>
<tr>
    <td class="name">Series</td>
    <td class="desc">Core i5</td>
</tr>
<tr>
    <td class="name">Cores</td>
    <td class="desc">4</td>
</tr>
<tr>
    <td class="name">Socket</td>
    <td class="desc">LGA 1156</td>

<tr>
    <td class="name">Brand</td>
    <td class="desc">AMD</td>
</tr>
<tr>
    <td class="name">Series</td>
    <td class="desc">Phenom II X4</td>
</tr>
<tr>
    <td class="name">Cores</td>
    <td class="desc">4</td>
</tr>
<tr>
    <td class="name">Socket</td>
    <td class="desc">Socket AM3</td>
</tr>

Am Ende hätte ich gerne eine Klasse für eine CPU (die bereits eingerichtet ist), die aus einem Brand-, Serien-, Cores- und Socket-Typ besteht, um alle Daten zu speichern. Dies ist der einzige Weg, den ich mir vorstellen kann, um dies zu tun:

if(parsedDocument.xpath(tr/td[@class="name"])=='Brand'):
    CPU.brand = parsedDocument.xpath(tr/td[@class="name"]/nextsibling?).text

Und das für den Rest der Werte. Wie würde ich das Nextsibling erreichen und gibt es einen einfacheren Weg, dies zu tun?

Corey Farwell
quelle

Antworten:

204

Wie würde ich das Nextsibling erreichen und gibt es einen einfacheren Weg, dies zu tun?

Sie können verwenden :

tr/td[@class='name']/following-sibling::td

aber ich würde lieber direkt verwenden :

tr[td[@class='name'] ='Brand']/td[@class='desc']

Dies setzt voraus, dass :

  1. Der Kontextknoten, anhand dessen der XPath-Ausdruck ausgewertet wird, ist das übergeordnete trElement aller Elemente - in Ihrer Frage nicht dargestellt.

  2. Jedes trElement hat nur eines tdmit classAttributwert 'name'und nur eines tdmit classAttributwert 'desc'.

Dimitre Novatchev
quelle
Beachten Sie, dass Sie bei der Verwendung von Klassen vorsichtig sein müssen. Wenn Ihre 'name'-Klassenelemente gleichzeitig eine andere Klasse haben, td[@class='name']wird dies unterbrochen. Siehe diese Frage für Details.
gm2008
@ gm2008, Ja, falls der Wert des @ class-Attributs mehr als eine Klasse enthält, lautet das zu verwendende Prädikat : contains(concat(' ', @class, ' '), ' name ') . In dieser Frage haben die @ class-Attribute jedoch nur einzelne Werte.
Dimitre Novatchev
Relativ zu einem Element:./following-sibling::td
John Gietzen
2
@JohnGietzen, Re: „ Im Vergleich zu einem Element“ - Sie meinen , wenn der Kontextknoten ist das Element wir interessiert sind , in diesem Fall Sie weglassen. ./. Wenn Sie das unmittelbar folgende Geschwister auswählen möchten, verwenden Sie: following-sibling::td[1]Andernfalls werden alle ausgewählt, wenn mehr als ein Geschwister vorhanden ist.
Dimitre Novatchev
12

Probieren Sie die following-siblingAchse ( following-sibling::td).

Philipp
quelle