Comment sélectionner la balise frère / xml suivante à l'aide de xpath


102

J'ai un fichier HTML (de Newegg) et leur HTML est organisé comme ci-dessous. Toutes les données de leur tableau de spécifications sont « desc » tandis que les titres de chaque section sont dans « nom » . Voici deux exemples de données provenant de pages 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>

En fin de compte, j'aimerais avoir une classe pour un processeur (qui est déjà configuré) qui se compose d'un type de marque, série, cœurs et socket pour stocker chacune des données. C'est le seul moyen auquel je peux penser pour y parvenir:

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

Et faire cela pour le reste des valeurs. Comment pourrais-je accomplir le nextsibling et existe-t-il un moyen plus simple de le faire?

Réponses:


205

Comment pourrais-je accomplir le nextsibling et y a-t-il un moyen plus simple de le faire?

Vous pouvez utiliser :

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

mais je préfère utiliser directement :

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

Cela suppose que :

  1. Le nœud de contexte, par rapport auquel l'expression XPath est évaluée, est le parent de tous les tréléments - non affiché dans votre question.

  2. Chaque trélément n'en a qu'un tdavec un classattribut valorisé 'name'et un seul tdavec un classattribut valorisé 'desc'.


Notez que vous devez faire attention à l'utilisation de la classe. Lorsque vos éléments de classe «nom» ont une autre classe en même temps, td[@class='name']se cassera. Voir cette question pour plus de détails.
gm2008

@ gm2008, Oui, dans le cas où il y a plus d'une classe de la valeur de l'attribut @class, le prédicat à utiliser est: contains(concat(' ', @class, ' '), ' name ') . Mais dans cette question, les attributs @class n'ont que des valeurs uniques.
Dimitre Novatchev

Par rapport à un élément:./following-sibling::td
John Gietzen

2
@JohnGietzen, Re: "Par rapport à un élément" - Vous voulez dire Si le nœud de contexte est l'élément qui nous intéresse. Dans ce cas, vous pouvez l'omettre ./. De plus, si vous souhaitez sélectionner le frère suivant immédiat, utilisez following-sibling::td[1]:, sinon, s'il y a plus d'un frère suivant, tous seront sélectionnés.
Dimitre Novatchev

12

Essayez l' following-siblingaxe ( following-sibling::td).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.