Como selecionar a seguinte tag irmão / xml usando xpath


102

Eu tenho um arquivo HTML (da Newegg) e seu HTML está organizado como abaixo. Todos os dados em sua tabela de especificações são ' desc ', enquanto os títulos de cada seção estão em ' name. 'Abaixo estão dois exemplos de dados das páginas 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>

No final, gostaria de ter uma classe para uma CPU (que já está configurada) que consistisse em um tipo de Marca, Série, Núcleos e Soquete para armazenar cada um dos dados. Esta é a única maneira que consigo pensar para fazer isso:

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

E fazendo isso para o resto dos valores. Como eu realizaria o próximo e há uma maneira mais fácil de fazer isso?

Respostas:


205

Como eu realizaria o próximo e há uma maneira mais fácil de fazer isso?

Você pode usar :

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

mas prefiro usar diretamente :

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

Isso pressupõe que :

  1. O nó de contexto, em relação ao qual a expressão XPath é avaliada, é o pai de todos os trelementos - não é mostrado em sua pergunta.

  2. Cada trelemento tem apenas um tdcom classvalor de atributo 'name'e apenas um tdcom classvalor de atributo 'desc'.


Observe que você deve ter cuidado ao usar a classe. Quando os elementos da sua classe 'name' tiverem qualquer outra classe ao mesmo tempo, td[@class='name']haverá falha. Veja esta pergunta para detalhes.
gm2008

@ gm2008, Sim, no caso de haver mais de uma classe no valor do atributo @class, o predicado de uso é: contains(concat(' ', @class, ' '), ' name ') . Mas, nesta questão, os atributos @class têm apenas valores únicos.
Dimitre Novatchev

Em relação a um elemento:./following-sibling::td
John Gietzen

2
@JohnGietzen, Re: "Relativo a um elemento" - Você quer dizer se o nó de contexto é o elemento no qual estamos interessados. Neste caso, você pode omitir ./. Além disso, se você quiser selecionar o irmão seguinte imediato, use:, following-sibling::td[1]caso contrário, se houver mais de um irmão seguinte, todos serão selecionados.
Dimitre Novatchev

12

Experimente o following-siblingeixo ( following-sibling::td).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.