【问题标题】:Nokogiri Ruby - Remove the <!DOCTYPE ... > from the output htmlNokogiri Ruby - 从输出 html 中删除 <!DOCTYPE ... >
【发布时间】:2018-10-12 18:44:38
【问题描述】:

我正在使用 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 中删除它。

【问题讨论】:

    标签: ruby nokogiri


    【解决方案1】:

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

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

    当在片段上调用 ​​to_sto_html 时,doctype 行将被省略,&lt;html&gt;&lt;body&gt; 标记也会被 Nokogiri 添加(如果它们尚不存在)。

    【讨论】:

      【解决方案2】:

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

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

      如果你也需要收集&lt;head&gt; 并避免&lt;DOCTYPE&gt; 那么

      #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 #=&gt; true

      【讨论】:

      • 如果他想嵌入它,这可能是正确的解决方案
      • 在这个答案的帮助下,我设法解决了同样的挑战。我将在单独的答案中详细说明。
      【解决方案3】:

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

      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
      

      【讨论】:

        【解决方案4】:

        我设法通过HTML::DocumentHTML::DocumentFragment 解决了这个问题。

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

        • 作为参考,HTML::Document 添加了 &lt;!DOCTYPE&gt; 声明,并且还将您的文档包装到 &lt;html&gt;&lt;body&gt; 实体中(如果它们尚未出现在您的文档中)。同样,HTML::DocumentFragment 将使用&lt;p&gt; 实体包装您的片段。

        我没有花太多时间深入研究 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 无济于事。

        无论如何,虽然这个解决方案对我来说有点笨拙,但它确实有效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-29
          • 2010-12-17
          • 2013-12-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-01
          相关资源
          最近更新 更多