2011-10-27 61 views
10

我遇到了一個問題,如何從當前元素中找到第一級的孩子? 比如我的html:在nokogiri rails找到第一級的孩子

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

我使用引入nokogiri鋼軌:

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

它返回所有trtable。 但我只需要2表的第一級。

回答

19

當你這樣說:

table = page.css('table') 

你抓住這兩個表,而不是僅僅頂級表。所以,你可以回到文檔根目錄和mosch說使用僅在第一個表匹配的行的選擇,或者你可以修復table是隻有外部表是這樣的:

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

或即使是這樣(取決於HTML真實結構):

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

table這些也許是一個(感謝Phrogz,再次):

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

你可能想提到'page.at('table')'或'page.at_css('table')'而不是' page.css( '表')。first'。 – Phrogz

+0

@Progrog:謝謝,我也把這些混在一起。 –

+0

冒着過分的風險:page.xpath('// table [not(ancestor :: * [1] [name()=「table」])]') – pguardiario

5

你可以做

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

也許你必須選擇適應您的容器元素(我選擇了「身體」在這裏)

+0

沒有,因爲它這個CA你也選擇了嵌套在內表中的tr元素 – WarHog

+0

確實,謝謝!編輯答案。 – moritz

+1

你也可以通過'table.css('> tr')'獲得表 –

1

作爲另一種方式,你可以嘗試使用這樣的事情:

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 

在該示例中,「/表/ TR」表達式表示所要求的元素的絕對路徑 - 「TR」在我們的情況。

+0

的直接後代,因爲這是html,你真的想使用Nokogiri :: HTML。同樣,你的xpath中的尾部斜線也會打破它。 – pguardiario

+0

糟糕,這些都是我的錯別字 - 你是完全正確的,我的道歉:) – WarHog