如何避免刮
问题描述:
当我从刮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"
为什么会出现这种情况?如何避免它?
答
这是一个很容易解决的问题,不从读取有关如何text
的行为上的节点集与一个节点(或元件)一起使用时的文档的结果。
的NodeSet documentation说text
将:
获取所有包含节点的内部文本对象
这也就是我们所看到的与发生:
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
也称为:
text
,inner_text
返回此节点的内容。