如何使用Nokogiri获取<p>标签父类名?</p>

时间:2013-08-19 16:27:32

标签: ruby nokogiri

我正在尝试获取<p>标记的父类名称?

<div class="entry-content">
   <p>Some text...</p>
</div>

我怎样才能获得这个?

4 个答案:

答案 0 :(得分:5)

有些人发现使用css和nokogiri parent方法比xpath更容易阅读/维护:

html = %q{
<div class="entry-content">
   <p>Some text...</p>
</div>
}

doc = Nokogiri::HTML(html)
doc.css('p').each do |p|
    puts p.parent.attr('class')
end

答案 1 :(得分:3)

使用像//p/..//*[p]这样的XPath(任何深度的任何&#34; p&#34;元素的父级)。

str =<<__HERE__
<div class="entry-content">
   <p>Some text...</p>
</div>
__HERE__

html = Nokogiri::HTML(str)
p_parents = html.xpath('//p/..') # => NodeSet containing the "<div>" element.
p_parents.each do |node|
  puts node.attr('class') # => "entry-content"
end

答案 2 :(得分:2)

我会使用#at_css,而不是css

require 'nokogiri'

str =<<__HERE__
<div class="entry-content">
   <p>Some text...</p>
</div>
__HERE__

html = Nokogiri::HTML(str)
p_parent = html.at_css('p').parent
p_parent.name # => "div"
p_parent['class'] # => "entry-content"

答案 3 :(得分:1)

这是XPath的一个很好的用例。我就是这样做的:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<div class="entry-content">
   <p>Some text...</p>
</div>
EOT

puts doc.at('//p/..')['class']

哪个输出:entry-content

如果您可以拥有多个<p>代码并需要访问其父级的类,请使用:

puts doc.search('//p/..').map{ |n| n['class'] }

再次输出:entry-content

在任何一种情况下,使用[]表示法都是检索与标记参数关联的值的快捷方式。

而且,正如我们在列出目录时在* nix命令行中看到..一样,..表示父元素。

Nokogiri支持使用CSS选择器浏览文档,但CSS长时间不支持“父”访问器。 CSS 4确实有办法实现,但Nokogiri v1.6.0似乎还不支持它。例如,我们应该能够使用像$* > p这样的选择器,但它不起作用:

doc.at('$* > p')
Nokogiri::CSS::SyntaxError: unexpected '$' after ''

doc.at('* > p')
=> #<Nokogiri::XML::Element:0x3ff7c099f528 name="p" children=[#<Nokogiri::XML::Text:0x3ff7c099f2e4 "Some text...">]>

$是CSS中的一个标记,表示选择器的特定部分是我们感兴趣的内容。有关详细信息,请参阅“Determining the Subject of a Selector”。一旦Nokogiri支持“主题”,我们就可以简化我们的CSS选择器及其附带的Ruby代码,因为我们不需要使用parent方法来设置父节点。在那之前,我们仍然有使用parent的旧作品。