Nokogiri, как получить родительский текст, а не дочерний текст и ссылаться на текст обратно к родителю - PullRequest
1 голос
/ 06 декабря 2009

Допустим, у меня есть этот образец:

  page = "<html><body><h1 class='foo'></h1><p class='foo'>hello people<a href='http://'>hello world</a></p></body></html>"
    @nodes = []
    Nokogiri::HTML(page).traverse do |n|
       if n[:class]  == "foo"
          @nodes << {:name => n.name, :xpath => n.path, :text => n.text }
       end
    end

результаты для n.text будут hello peoplehello world, я хочу сделать это так, чтобы я мог получить родительский текст и его дочерние тексты, но связать их с их тегом

так что результат будет что-то вроде

@nodes[0][:text]=""
@node[1][:text]= [{:Elementtext1 => "hello people", :ElementObject1 => elementObject},{:Elementtext2 => "hello world", :ElementObject2 => elementObject}]

1 Ответ

1 голос
/ 07 декабря 2009

Вот и мы

require 'rubygems'
require 'nokogiri'

doc = Nokogiri::HTML(DATA.read)

nodes = doc.root.css('.foo').collect do |n|
  { :name => n.name,
    :xpath => n.path,
    :text => n.xpath('.//text()').collect{|t|
      { :parent => t.parent.name,
        :text => t.text }}}
end

p nodes

__END__
<html>
<body>
<h1 class='foo'></h1>
<p class='foo'>hello people<a href='http://'>hello world</a></p>
</body>
</html>

вы не можете получить доступ ко всем элементам, используя traverse, поскольку он посещает только прямые дочерние элементы корня. Следовательно, я использую селектор css, чтобы получить все элементы с классом foo. И затем для каждого найденного элемента я использую селектор xpath, чтобы получить все текстовые узлы под ним.

...