2017-04-24 51 views
1

当我从刮HTML或XML来提取文本的几个相关节点从节点加入所有文字,所有的文本连接成一个长字符串,使其无法恢复单个文本字符串。如何避免刮

例如:

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p>foo</p> 
    <p>bar</p> 
    <p>baz</p> 
    </body> 
</html> 
EOT 

doc.search('p').text # => "foobarbaz" 

但我想要的是:

["foo", "bar", "baz"] 

刮XML时,同样的情况:

doc = Nokogiri::XML(<<EOT) 
<root> 
    <block> 
    <entries>foo</entries> 
    <entries>bar</entries> 
    <entries>baz</entries> 
    </block> 
</root> 
EOT 

doc.search('entries').text # => "foobarbaz" 

为什么会出现这种情况?如何避免它?

回答

3

这是一个很容易解决的问题,不从读取有关如何text的行为上的节点集与一个节点(或元件)一起使用时的文档的结果。

NodeSet documentationtext将:

获取所有包含节点的内部文本对象

这也就是我们所看到的与发生:

doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p>foo</p> 
    <p>bar</p> 
    <p>baz</p> 
    </body> 
</html> 
EOT 

doc.search('p').text # => "foobarbaz" 

,因为:

doc.search('p').class # => Nokogiri::XML::NodeSet 

相反,我们希望让每一个节点,并提取其文本:

doc.search('p').first.class # => Nokogiri::XML::Element 
doc.search('p').first.text # => "foo" 

这是可以做到使用map

doc.search('p').map { |node| node.text } # => ["foo", "bar", "baz"] 

红宝石允许我们编写更简明使用:

doc.search('p').map(&:text) # => ["foo", "bar", "baz"] 

同样的事情是否适用于我们正在与HTML或XML的工作,因为HTML是XML的一个更宽松的版。

的节点已在其嵌入式文本得到几个别名的方法。从the documentation

#content ⇒ Object

也称为:textinner_text

返回此节点的内容。