我是Ruby on Rails的新手。我想在Nokogiri中使用CSS解析来选择HTML页面上的整个div,而不是只选择嵌套元素。例如,如果我选择:

@sel = @page.css("div").select{|li| li['class']== "test" }
@sel_net = @sel.css("span").select{|li| li['class']== "test1" }


它将从div中选择所有跨度,其中class等于test1。但是,如果我要选择整个外部div(其跨度为class名为test1)怎么办?那可能吗?

最佳答案

如果我对您的理解正确,那么您有一些类似于以下内容的HTML:

<div>
  This is the div we want.
  <span class="test1">Span contents</span> Other contents
</div>
<div>
  We don't want this div.
  <span class="something else">Not this</span> one
</div>


而您要选择第一个div,而不要选择第二个。

CSS无法做到这一点(据我所知,Nokogiri实现的任何CSS扩展都不可能做到),但是可以使用XPath完成。

一个简单的XPath查询将选择我们想要的div,如下所示:

//div[span[@class = 'test1']]


这可以理解为“具有div元素的所有span元素作为具有class属性且值为test1的直接子代的元素”。

该查询仅测试class属性是否与test1直接匹配,因此如果该类是“test1 otherclass”之类的,则不会匹配。要使其像CSS一样工作,您需要将测试更改为以下内容:

[contains(concat(' ', normalize-space(@class), ' '), ' test1 ')]


此外,原始查询仅选择span的直接子元素。如果要匹配的其他元素中有div,则需要在查询中使用span轴。

放在一起:

//div[descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' test1 ')]]


可以理解为“所有在descendant类中具有div后代的span元素(在CSS意义上)”。

显然,要使用此方法,您需要使用test1 method而不是xpath方法:

divs = @page.xpath("//div[descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' test1 ')]]")

10-05 20:44
查看更多