Як вибрати наступний тег sibling / xml за допомогою xpath


102

У мене є HTML-файл (від Newegg), і їх HTML організовано як нижче. Усі дані в таблиці їх специфікацій є " desc ", а заголовки кожного розділу - у " name". 'Нижче наведено два приклади даних зі сторінок 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>

Зрештою, я хотів би мати клас для центрального процесора (який вже налаштований), який складається з типу бренда, серії, ядер та сокета для зберігання кожного з даних. Це єдиний спосіб, що я можу зробити, щоб зробити це:

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

І це робимо для решти цінностей. Як би я здійснив зв'язок і чи є простіший спосіб зробити це?

Відповіді:


205

Як би я здійснив зв'язок і чи є простіший спосіб зробити це?

Ви можете використовувати :

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

але я краще скористаюся безпосередньо :

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

Це передбачає, що :

  1. Контекстний вузол, за яким оцінюється вираз XPath, є основним з усіх trелементів - не відображається у вашому запитанні.

  2. Кожен trелемент має лише один tdз classатрибутом, що оцінюється, 'name'і лише один tdз classатрибутом 'desc'.


Зауважте, що вам слід бути обережними щодо використання класу. Коли елементи вашого класу 'name' одночасно мають будь-який інший клас, td[@class='name']вони порушуються. Детальніше див. У цьому питанні .
gm2008

@ Gm2008, Та, в разі , якщо є більш ніж один клас в значенні атрибута @class, предикат для використання є: contains(concat(' ', @class, ' '), ' name ') . Але в цьому питанні атрибути @class мають лише одне значення.
Димитрій Новатчев

Відносно елемента:./following-sibling::td
Джон Гітцен

2
@JohnGietzen, Re: "Відносно елемента" - Ви маєте на увазі, якщо контекстний вузол є цікавим для нас елементом. У цьому випадку його можна опустити ./. Крім того, якщо ви хочете вибрати найближчого наступного брата, скористайтеся: following-sibling::td[1]інакше, якщо є більше одного наступного брата, будуть вибрані всі.
Димитрій Новатчев

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.