2012-08-16 121 views
7

是否有任何干净的方式来获取与Nokogiri文本节点的内容?现在我正在使用Nokogiri文本节点内容

some_node.at_xpath("//whatever").first.content 

这看起来真的很详细,只是获取文本。

回答

12

你想只有的文字?

doc.search('//text()').map(&:text) 

也许你不想要所有的空白和噪音。如果你想只包含文字字符的文本节点,

doc.search('//text()').map(&:text).delete_if{|x| x !~ /\w/} 

编辑:看来,你只是想在单个节点的文本内容:

some_node.at_xpath("//whatever").text 
+0

我接受这个答案,不是因为它是我想要的,而是因为它包含我想要的 - 文本方法。谢谢! – cbmanica 2012-08-16 21:29:57

+0

只是后续工作:如果你想找到所有的非空白文本节点,并且你正在使用Rails,那么你有'present?'和'blank?'方法。每一个都是等价的:'doc.search('// text()')。map(&:text).delete_if&:blank?''或'doc.search('// text()')。map &:text).keep_if&:present?' – 2015-02-21 21:59:21

7

只要看看文本节点:

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<html> 
<body> 
<p>This is a text node </p> 
<p> This is another text node</p> 
</body> 
</html> 
EOT 

doc.search('//text()').each do |t| 
    t.replace(t.content.strip) 
end 

puts doc.to_html 

,输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html><body> 
<p>This is a text node</p> 
<p>This is another text node</p> 
</body></html> 

顺便说一句,你的代码示例不起作用。 at_xpath("//whatever").first是多余的,会失败。 at_xpath只会找到第一个出现,返回一个节点。 first在这一点上是多余的,如果它能工作,但它不会因为Node没有first方法。


我有<data><foo>bar</foo></bar>,我如何才能在 “酒吧” 的文本,而不做doc.xpath_at("//data/foo").children.first.content

假设doc包含解析DOM:

doc.to_xml # => "<?xml version=\"1.0\"?>\n<data>\n <foo>bar</foo>\n</data>\n" 

获得第一次出现:

doc.at('foo').text  # => "bar" 
doc.at('//foo').text  # => "bar" 
doc.at('/data/foo').text # => "bar" 

获取所有事件和占据第一位:

doc.search('foo').first.text  # => "bar" 
doc.search('//foo').first.text # => "bar" 
doc.search('data foo').first.text # => "bar" 
+0

呃,对不起,我的意思children.first。内容。你的例子并不完全是我想要的 - 假设我有 bar,我如何在没有做doc.xpath_at(“// data/foo”).children.first的情况下获得“bar”文本。内容? – cbmanica 2012-08-16 20:03:05

+0

它真的*重要的是清楚你想要什么。否则我们无法帮助你。查看添加的内容。 – 2012-08-17 04:39:35

+0

我以为我是 - 我认为xpath_at使它变得非常清楚,我确切知道我正在寻找的节点,并且只是以一种愚蠢的方式获取它们的内容。 – cbmanica 2012-08-17 16:05:11