Cara memilih tag saudara / xml berikut menggunakan xpath

102

Saya memiliki file HTML (dari Newegg) dan HTML-nya diatur seperti di bawah ini. Semua data dalam tabel spesifikasinya adalah ' desc ' sedangkan judul tiap bagian ada di ' name. 'Di bawah ini adalah dua contoh data dari halaman Newegg.

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

Pada akhirnya saya ingin memiliki kelas untuk CPU (yang sudah diatur) yang terdiri dari jenis Merek, Seri, Cores, dan Socket untuk menyimpan setiap data. Inilah satu-satunya cara yang dapat saya pikirkan untuk melakukan ini:

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

Dan melakukan ini untuk nilai-nilai lainnya. Bagaimana saya menyelesaikan tahap berikutnya dan adakah cara yang lebih mudah untuk melakukan ini?

Corey Farwell
sumber

Jawaban:

205

Bagaimana saya menyelesaikan tahap berikutnya dan adakah cara yang lebih mudah untuk melakukan ini?

Anda dapat menggunakan :

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

tetapi saya lebih suka menggunakan secara langsung :

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

Ini mengasumsikan bahwa :

  1. Node konteks, yang digunakan untuk mengevaluasi ekspresi XPath adalah induk dari semua trelemen - tidak ditampilkan dalam pertanyaan Anda.

  2. Setiap trelemen hanya memiliki satu tddengan classatribut yang dihargai 'name'dan hanya satu tddengan classatribut yang dihargai 'desc'.

Dimitre Novatchev
sumber
Perhatikan bahwa Anda harus berhati-hati dalam menggunakan kelas. Ketika elemen kelas 'nama' Anda memiliki kelas lain pada saat yang sama, td[@class='name']akan rusak. Lihat pertanyaan ini untuk detailnya.
gm2008
@ gm2008, Ya, jika ada lebih dari satu kelas di nilai dari atribut @class, predikat penggunaan adalah: contains(concat(' ', @class, ' '), ' name ') . Namun dalam pertanyaan ini, atribut @class hanya memiliki nilai tunggal.
Dimitre Novatchev
Sehubungan dengan suatu elemen:./following-sibling::td
John Gietzen
2
@JohnGietzen, Re: "Relatif dengan elemen" - Maksud Anda Jika node konteks adalah elemen yang kami minati. Dalam hal ini Anda dapat mengabaikan ./. Selain itu, jika Anda ingin memilih saudara kandung berikut, gunakan following-sibling::td[1]:, jika tidak, jika ada lebih dari satu saudara kandung berikut, semua akan dipilih.
Dimitre Novatchev
12

Coba following-siblingsumbu ( following-sibling::td).

Philipp
sumber