2011-10-27 18 views
10

¿He enfrentado un problema de cómo encontrar niños de primer nivel del elemento actual? Por ejemplo, he html:encontrar niños de primer nivel en rieles de nokogiri

<table> 
    <tr>abc</tr> 
    <tr>def</tr> 
    <table> 
    <tr>second</tr> 
    </table> 
</table> 

estoy usando Nokogiri de rieles:

table = page.css('table') 
table.css('tr') 

Devuelve todas tr dentro table. Pero solo necesito 2 de ese primer nivel para la mesa.

Respuesta

19

Cuando se dice esto:

table = page.css('table') 

que estás agarrando ambas tablas en lugar de sólo la tabla de nivel superior. Por lo que puede volver a la raíz del documento y el uso de un selector que sólo coincide con las filas de la primera tabla como dice mosch o se puede fijar table ser sólo la tabla externa con algo como esto:

table = page.css('table').first 
trs = table.xpath('./tr') 

o incluso este (dependiendo de la estructura real de la HTML):

table = page.xpath('/html/body/table') 
trs = table.xpath('./tr') 

o tal vez uno de estos para table (gracias Phrogz, de nuevo):

table = page.at('table') 
table = page.at_css('table') 
# or various other CSS and XPath incantations 
+2

Es posible que desee mencionar 'page.at ('table')' o 'page.at_css ('table')' en lugar de ' page.css ('tabla'). primero'. – Phrogz

+0

@Phrogz: Gracias, también los tiré en la mezcla. –

+0

A riesgo de llevarlo demasiado lejos: page.xpath ('// table [not (ancestor :: * [1] [name() = "table"])]') – pguardiario

5

Usted puede hacer

rows = page.css('body > table > tr') 

Tal vez usted tiene que adaptar el selector hacia su elemento contenedor (he elegido 'cuerpo' aquí)

+0

No, porque este ca si también seleccionó el elemento tr anidado en la tabla interna – WarHog

+0

¡De hecho, gracias! Editado la respuesta. – moritz

+1

También puede hacer 'table.css ('> tr')' para obtener el descendiente directo de la tabla –

1

Como otra manera, se puede tratar de usar algo como esto :

text = <<HERE 
    <table> 
    <tr>abc</tr> 
    <tr>def</tr> 
    <table> 
     <tr>second</tr> 
    </table> 
    </table> 
HERE 
xml = Nokogiri::XML(text) 
xml.xpath("/table/tr/").each do |node| 
    puts node.text 
end 

En este ejemplo, la expresión '/ table/tr' representa una ruta absoluta al elemento requerido - 'tr' en nuestro caso.

+0

ya que esto es html, realmente quiere usar Nokogiri :: HTML. También la barra final en su xpath lo rompe. – pguardiario

+0

Vaya, estos son un par de errores tipográficos - tiene toda la razón, mis disculpas :) – WarHog

Cuestiones relacionadas