你如何利用Nokogiri消除HTML标签之间的差距?

时间:2012-01-23 00:01:45

标签: ruby nokogiri

说我有这种标记:

<li>    Some text </li>
<li> <strong>  Some text </strong> hello</li>

我需要确保在打开<li>标记之后和任何封闭的文本内容之前没有空白间隔。使用Nokogiri实现这一目标的最佳方法是什么?

期望的结果:

<li>Some text </li>
<li><strong>Some text </strong> hello</li>

3 个答案:

答案 0 :(得分:6)

删除整个文档中的所有前导/尾随空格:

doc.xpath('//text()').each do |node|
  if node.content=~/\S/
    node.content = node.content.strip
  else
    node.remove
  end
end

但请注意,这会将<p>Hello <b>World</b></p>变为<p>Hello<b>World</b></p>。您可能需要更精确地指定您想要的内容。

编辑:这是一个更好的解决方案,可以从作为元素第一个子节点的所有文本节点中删除前导空格,并从最后一个子节点的文本节点中删除所有尾随空格:

doc.xpath('//text()[1]').each{ |t|      t.content = t.content.lstrip }
doc.xpath('//text()[last()]').each{ |t| t.content = t.content.rstrip }

见过:

html = '<ul>
  <li>    First text </li>
  <li> <strong>  Some text </strong> </li>
  <li> I am <b>  embedded  </b> and need <i>some </i>  <em>spaces</em>. </li>
</ul>'

require 'nokogiri'
doc = Nokogiri.HTML(html)
doc.xpath('//text()[1]').each{ |t|      t.content = t.content.lstrip }
doc.xpath('//text()[last()]').each{ |t| t.content = t.content.rstrip }
puts doc.root
#=> <html><body><ul>
#=> <li>First text</li><li><strong>Some text</strong></li>
#=>   <li>I am <b>embedded</b> and need <i>some</i>  <em>spaces</em>.</li></ul></body></html>

编辑#2:以下是如何从<li>前面的文字节点剥离它:

doc.xpath('//li/text()[1]').each{ |t| t.content = t.content.lstrip }

答案 1 :(得分:0)

你会遍历每个删除前导空格的li,直到找到一些文本:

doc.css('li').each do |li|
    li.traverse do |node|
        node.content = node.content.gsub(/^\s+/,'')
        break unless node.content.empty?
    end
end

答案 2 :(得分:0)

操纵Nokogiri::HTML.fragment时,xpath("//text()")似乎无效。

所以我想出的是

doc.traverse do |node|
  if node.is_a? Nokogiri::XML::Text
    node.content = node.content.lstrip if node.previous_element&.description&.block?
    node.content = node.content.lstrip if node.previous_element.nil? && node.parent.description&.block?
    node.content = node.content.rstrip if node.next_element&.description&.block?
    node.content = node.content.rstrip if node.next_element.nil? && node.parent.description&.block?
    node.remove if node.content.empty?
  end
end

注意:使用Ruby 2.3语法

相关问题