阻止Nokogiri添加DOCTYPE和meta标签?

CSt*_*ess 6 html ruby nokogiri

我正在尝试使用Nokogiri将一些模板文件从一种格式转换为另一种格式.但它不断添加标签.我试图阻止它添加Doctype和meta标签,但无法弄明白.我试过了

@doc = Nokogiri::HTML.parse(r)
Run Code Online (Sandbox Code Playgroud)

但是这会添加标签.我也试过了

@doc = Nokogiri::HTML.fragment(r)
Run Code Online (Sandbox Code Playgroud)

在建议的" 如何防止引入nokogiri从加入<!DOCTYPE>标记? ",但删除所有<html>,<head><body>标签是在文档中.

如果重要,我的阅读文件的代码是:

f = File.read(infile)
r = f.gsub(/<tmpl_var ([^>]*)>/, '{{{\1}}}')
@doc = Nokogiri::HTML.fragment(r)
Run Code Online (Sandbox Code Playgroud)

我需要gsub事先做,因为我需要替换<tmpl_var>不合适的HTML标签并导致更多问题.

使用时HTML.fragment(r),我得到一个htmlParseStartTag: misplaced <html> tag(对,以及类似的错误,错误<body><head>).

有没有办法阻止它进行这些添加?

转换示例:

之前:

<html>
    <head>
        <script>
            var x = "y";
        </script>
    </head>
    <body>
        <div>
            Stuff
        </div>
   </body>
</html>
Run Code Online (Sandbox Code Playgroud)

使用Parse之后:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script>
            var x = "y";
        </script>
    </head>
    <body>
        <div>
            Stuff
        </div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

使用后HTML.fragmentHTML::DocumentFragment.parse:

<script>
    var x = "y";
</script>

<div>
    Stuff
</div>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望它只输出前一节.(在真实的脚本中,我做了一堆修改).

the*_*Man 3

Nokogiri 可以被告知不要添加标准 HTML 标头。考虑这些:

require 'nokogiri'

doc = Nokogiri::HTML('<p>foo</p>')
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><p>foo</p></body></html>\n"

doc = Nokogiri::HTML.fragment('<p>foo</p>')
doc.to_html # => "<p>foo</p>"
Run Code Online (Sandbox Code Playgroud)

tmpl_var是 HTML 中的错误标签名称,因此{{{\1}}}要求 Nokogiri 尝试解析其中任何一个都会导致问题:

doc = Nokogiri::HTML.fragment('<templ_var p1="baz">foo</templ_var>')
doc.errors # => [#<Nokogiri::XML::SyntaxError: Tag templ_var invalid>]
Run Code Online (Sandbox Code Playgroud)

但你仍然可以修改 DOM:

doc.to_html # => "<templ_var p1=\"baz\">foo</templ_var>"
doc.search('templ_var').each { |t| t.name = 'bar'}
doc.to_html # => "<bar p1=\"baz\">foo</bar>"
Run Code Online (Sandbox Code Playgroud)

或者:

doc.to_html # => "<div><templ_var p1=\"baz\">foo</templ_var></div>"
doc.search('templ_var').each { |t| t.replace('{{{\1}}}') }
doc.to_html # => "<div>{{{\\1}}}</div>"
Run Code Online (Sandbox Code Playgroud)

把这些东西放在一起,再加上一些诡计:

doc = Nokogiri::HTML.fragment('<div><templ_var p1="baz">foo</templ_var></div>')

doc.to_html # => "<div><templ_var p1=\"baz\">foo</templ_var></div>"

doc.search('templ_var').each { |t| t.replace('{{{\1}}}') }
doc.to_html # => "<div>{{{\\1}}}</div>"

header = Nokogiri::XML.fragment('<html><body>')
header.at('body').children = doc
header.to_html # => "<html><body><div>{{{\\1}}}</div></body></html>"
Run Code Online (Sandbox Code Playgroud)

所以,我会追求类似的东西。

现在,为什么Nokogiri<html>在解析片段时要剥离标签?我不知道。<body>如果<head><html>缺失,则不会出现:

Nokogiri::HTML.fragment('<p>foo<p>').to_html 
# => "<p>foo</p><p></p>"
Nokogiri::HTML.fragment('<body><p>foo<p></body>').to_html 
# => "<body>\n<p>foo</p>\n<p></p>\n</body>"
Run Code Online (Sandbox Code Playgroud)

但如果<head><html>存在,它就会变得很奇怪:

Nokogiri::HTML.fragment('<head><style></style></head><body><p>foo<p></body>').to_html 
# => "<style></style><p>foo</p><p></p>"
Nokogiri::HTML.fragment('<html><head><style></style></head><body><p>foo<p></body></html>').to_html 
# => "<style></style><p>foo</p><p></p>"
Run Code Online (Sandbox Code Playgroud)

对我来说,这就像 Nokogiri 中的一个错误,因为我还没有看到任何记录该行为的内容。