使用Hpricot和Ruby获取另一个元素之后的元素

时间:2011-05-28 20:59:30

标签: ruby hpricot

我有以下HTML:

<ul class="filtering_new" width="50%">
     <li class="filter">1</li>
     <li class="filter">2</li>
     <script>Alert('1');</script>
     <li class="filter">3</li>
</ul>

如何使用li获取inner_html = 3

我试过这样:

page.search("//ul.filtering_new").each do |list|
     puts list.search("li").size  
end

其中page是HTML文档。

size = 2,但它应该是3。

我尝试在手动https://github.com/hpricot/hpricot/wiki/hpricot-challenge中做 但我甚至找不到<script

 list.search("script")

什么都不返回。

2 个答案:

答案 0 :(得分:2)

使用search时,我认为您不能将 XPath CSS选择器混淆。在你的例子中你做。尝试:

 //ul[@class='filtering_new']

ul.filtering_new

search内。

答案 1 :(得分:0)

Ruby中的大多数XML / HTML解析现在使用Nokogiri,所以我建议使用解析器。但是,Hpricot和Nokogiri都支持XPath和CSS,因此它们可以互换。

我会这样做:

html = <<EOT
<ul class="filtering_new" width="50%">
     <li class="filter">1</li>
     <li class="filter">2</li>
     <script>Alert('1');</script>
     <li class="filter">3</li>
</ul>
EOT

require 'nokogiri'

doc = Nokogiri::HTML(html)
li = doc.search('//li[@class="filter"]').select{ |n| n.text.to_i == 3 } 
li # => [#<Nokogiri::XML::Element:0x8053fc84 name="li" attributes=[#<Nokogiri::XML::Attr:0x8053fb6c name="class" value="filter">] children=[#<Nokogiri::XML::Text:0x80546f98 "3">]>]

找到候选节点,然后将它们作为NodeSet返回以进行迭代,根据节点的文本选择/拒绝它们。

li = doc.search('//li[text() = "3"]') 
li # => [#<Nokogiri::XML::Element:0x8053fc84 name="li" attributes=[#<Nokogiri::XML::Attr:0x8053fb6c name="class" value="filter">] children=[#<Nokogiri::XML::Text:0x80546f98 "3">]>]

将更多的比较卸载到底层的libXML库,它运行得更快。