Nokogiri Ruby - 从输出html中删除

时间:2014-09-08 17:43:48

标签: ruby nokogiri

我正在使用nokogiri解析一个html文件并对其进行修改,然后将其输出到这样的文件中:

htext= File.open(inputOpts.html_file).read
h_doc = Nokogiri::HTML(htext)
File.open(outputfile, 'w+')  do |file|
  file.write(h_doc)
end

输出文件包含第一行:

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">

我不希望这样,因为我将html嵌入到另一个文件中,而且此标记导致了问题。

问题是如何从h_doc中删除它。

4 个答案:

答案 0 :(得分:4)

根据您要执行的操作,您可以将HTML解析为DocumentFragment

h_doc = Nokogiri::HTML::DocumentFragment.parse(htext)

在片段上调用to_sto_html时,将省略doctype行,Nokogiri添加的<html><body>标记也会被省略本。

答案 1 :(得分:3)

这取决于您的需求。如果您需要的只是身体那么

h_doc.at_xpath("//body") #this will just pull the data from the <body></body> tags 

如果您还需要收集<head>,请避开<DOCTYPE>然后

#this will capture everything between the <head></head> and <body></body> tags
h_doc.xpath("//head") + h_doc.xpath("//body") 

这样的事情

h_doc = Nokogiri::HTML(open(input_opts.html_file))
File.open(outputfile,'w+') do |file|
  #for just <body>
  file << h_doc.at_xpath("//body").to_s
  #for <head> and <body>
  file << (h_doc.xpath("//head") + h_doc.xpath("//body")).to_s
end

body的通知我使用了#at_xpath因为这会返回Nokogiri::Element,但在合并它们时我使用了#xpath,因为这将返回Nokogiri::XML::NodeSet。不用担心这部分只是用于组合而且html会出现相同的情况,例如: h_doc.at_xpath("//head").to_s == h_doc.xpath("//head").to_s #=> true

答案 2 :(得分:0)

读取输入文件时可以忽略第一行:

htext= File.readlines(inputOpts.html_file)[1..-1].join
h_doc = Nokogiri::HTML(htext)
File.open(outputfile, 'w+')  do |file|
  file.write(h_doc)
end

答案 3 :(得分:0)

我设法同时使用HTML::DocumentHTML::DocumentFragment来解决此问题。

  • 对于背景,我使用Nokogiri解析和修改HTML的“模板”,“部分”和/或“组件”。这意味着我遇到的文件不是有效的HTML文档。相反,它们是由我使用的框架整理在一起的HTML文档的一部分。

  • 供参考,HTML::Document添加<!DOCTYPE>声明,还将文档包装到<html><body>实体中(如果它们尚未出现在文档中)。同样,HTML::DocumentFragment将用<p>实体包裹您的片段。

我没有花太多时间去挖掘Nokogiri库代码来了解这些附加实体的位置,而是决定接受这种自以为是的实现并加以解决。

解决方案

这是我写出修改后的HTML的方式:

html_str = doc.xpath("//body").children.to_html(encoding: 'UTF-8')
File.open(_filename, 'w') {|f| f.write(html_str)}

最终词

这似乎比应该做的难。我什至尝试使用SaveOptions设置save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION无济于事。

在任何情况下,尽管按我的喜好此解决方案都有些麻烦,但它仍然有效。