65

How can I remove <img> tags using Nokogiri?

I have the following code but it wont work:

# str = '<img src="canadascapital.gc.ca/data/2/rec_imgs/5005_Pepsi_H1NB.gif"/…; testt<a href="#">test</a>tfbu' 

f = Nokogiri::XML.fragment(str)
f.search('//img').each do |node| 
  node.remove
end
puts f
Nakilon
  • 34,866
  • 14
  • 107
  • 142
all jazz
  • 2,007
  • 2
  • 21
  • 37

2 Answers2

86

have a try!

f = Nokogiri::XML.fragment(str)

f.search('.//img').remove
puts f
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
xds2000
  • 1,221
  • 13
  • 17
16

I prefer CSS over XPath, as it's usually much more readable. Switching to CSS:

require 'nokogiri'

doc = Nokogiri::HTML('<html><body><img src="foo"><img src="bar"></body></html>')

After parsing the document looks like:

doc.to_html
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n<img src=\"foo\"><img src=\"bar\">\n</body></html>\n"

Removing the <img> tags:

doc.search('img').each do |src|
  src.remove
end

Results in:

doc.to_html
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body></body></html>\n"
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • 2
    Since your block is just calling a method on each iterable, if you want to be fancy you can do symbol to proc: `doc.search('img').each(&:remove)`. – Tyler James Young Apr 16 '20 at 04:19
  • Yes, but back then, in 2013, we didn't have that fancy ability. – the Tin Man Apr 16 '20 at 05:20
  • 3
    I'm from the future! :) Thanks for this answer. This one and others of yours have been helping me a lot as I'm making Ruby scripts to change large batches of HTML files and automate myself out of a (menial component of my) job. – Tyler James Young Apr 17 '20 at 16:46
  • It's nice to know the answers help; That's the whole point of SO, teaching and passing on what we've learned. – the Tin Man Apr 18 '20 at 20:42