Cómo seleccionar la siguiente etiqueta de hermano / xml usando xpath


102

Tengo un archivo HTML (de Newegg) y su HTML está organizado como se muestra a continuación. Todos los datos en su tabla de especificaciones son " desc ", mientras que los títulos de cada sección están en " nombre " . A continuación se muestran dos ejemplos de datos de las páginas de 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>

Al final, me gustaría tener una clase para una CPU (que ya está configurada) que consta de un tipo de Marca, Serie, Núcleos y Socket para almacenar cada uno de los datos. Esta es la única forma en que puedo pensar para hacer esto:

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

Y haciendo esto para el resto de valores. ¿Cómo podría lograr el siguiente hermano y hay una forma más fácil de hacerlo?

Respuestas:


205

¿Cómo podría lograr el siguiente hermano y hay una forma más fácil de hacerlo?

Puede utilizar :

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

pero prefiero usar directamente :

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

Esto supone que :

  1. El nodo de contexto, contra el cual se evalúa la expresión XPath, es el padre de todos los trelementos, no se muestra en su pregunta.

  2. Cada trelemento tiene solo uno tdcon classatributo valorado 'name'y solo uno tdcon classatributo valorado 'desc'.


Tenga en cuenta que debe tener cuidado al usar class. Cuando los elementos de su clase 'nombre' tengan cualquier otra clase al mismo tiempo, td[@class='name']se romperán. Consulte esta pregunta para obtener más detalles.
GM2008

@ gm2008, Sí, en caso de que haya más de una clase en el valor del atributo @class, el predicado de uso es: contains(concat(' ', @class, ' '), ' name ') . Pero en esta pregunta, los atributos @class tienen solo valores únicos.
Dimitre Novatchev

Relativo a un elemento:./following-sibling::td
John Gietzen

2
@JohnGietzen, Re: "Relativo a un elemento" - Quieres decir si el nodo de contexto es el elemento que nos interesa. En este caso puedes omitir ./. Además, si desea seleccionar el hermano siguiente inmediato, utilice:, de lo following-sibling::td[1]contrario, si hay más de un hermano siguiente, se seleccionarán todos.
Dimitre Novatchev

12

Pruebe el following-siblingeje ( following-sibling::td).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.