Как вы убираете пробелы между HTML-тегами с помощью Nokogiri? - PullRequest
2 голосов
/ 23 января 2012

Скажите, у меня есть такая разметка:

<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 ]

6 голосов
/ 23 января 2012

Удаление всех начальных / конечных пробелов во всем документе:

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 }
0 голосов
/ 24 апреля 2017

При манипулировании 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

0 голосов
/ 23 января 2012

Вы будете обходить каждую строку, удаляя начальные пробелы, пока не найдете текст:

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