开发者

How to replace HTML nodes using Nokogiri

开发者 https://www.devze.com 2023-01-11 03:45 出处:网络
I have an HTML file, in which, all <div class=\"replace-me\"> </div> must be replaced with <video src=\'my_video.mov\'></video>

I have an HTML file, in which, all

<div class="replace-me">
</div>

must be replaced with

<video src='my_video.mov'></video>

The code is:

doc.css("div.replace-me").each do |div|
  div.replace "<video src='my_video.mov'></video>"
end

It's simple, but, unfortunately, it does't work for me. Nokogiri crashes with the following error:

开发者_StackOverflow中文版
undefined method `children' for nil:NilClass
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/whiny_nil.rb:52:in `method_missing'
/Library/Ruby/Gems/1.8/gems/nokogiri-1.4.2/lib/nokogiri/html/document_fragment.rb:16:in `initialize'
/Library/Ruby/Gems/1.8/gems/nokogiri-1.4.2/lib/nokogiri/xml/node.rb:424:in `new'
/Library/Ruby/Gems/1.8/gems/nokogiri-1.4.2/lib/nokogiri/xml/node.rb:424:in `fragment'
/Library/Ruby/Gems/1.8/gems/nokogiri-1.4.2/lib/nokogiri/xml/node.rb:776:in `coerce'
/Library/Ruby/Gems/1.8/gems/nokogiri-1.4.2/lib/nokogiri/xml/node.rb:331:in `replace'

Replacing with a div works:

doc.css("div.replace-me").each do |div|
  div.replace "<div>Test</div>"
end

Is this a Nokogiri bug, or did I do something wrong?

The same issue occurs with add_child, inner_html and other setters for this purpose.


I will quote my comment from your previous question:

This happens because of HTML strictness (HTML has a predefined set of elements). Replace Nokogiri::HTML( self.content ) with Nokogiri::XML( self.content ) and do not forget to add a DOCTYPE declaration manually later.


If you look into the log, the part you chose with Nokogiri turns nil.

Try it this way:

doc.css(".replace-me").each do |div|
 div.replace "<video src='my_video.mov'></video>"
end

Or you may need to specify which element you want to replace.


I can't duplicate the problem. Granted, the question is old, but this works:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<div class="replace-me">
</div>
EOT

It could have been a Ruby 1.8 issue, an issue with that version of Nokogiri, or something was wrong in your libXML... it's hard to say given the information in the question.

doc.at('div.replace-me').replace("<video src='my_video.mov'></video>")
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" +
#    "<video src=\"my_video.mov\"></video>\n" +
#    "</body></html>\n"
0

精彩评论

暂无评论...
验证码 换一张
取 消