停止Nokogiri添加DOCTYPE和元标记?
我试图使用Nokogiri将一些模板文件从一种格式转换为另一种格式。但它不断添加标签。我试图阻止它添加Doctype和元标记,但无法弄清楚。我试过停止Nokogiri添加DOCTYPE和元标记?
@doc = Nokogiri::HTML.parse(r)
但是增加了标签。我也试着
@doc = Nokogiri::HTML.fragment(r)
为“How to prevent Nokogiri from adding <DOCTYPE> tags?”的建议,但删除任何<html>
,<head>
,或者<body>
标签是在文档中。
如果它的事项,我读文件代码:
f = File.read(infile)
r = f.gsub(/<tmpl_var ([^>]*)>/, '{{{\1}}}')
@doc = Nokogiri::HTML.fragment(r)
我需要做一个gsub
事前,因为我需要更换<tmpl_var>
标签这不是正确的HTML,并导致更多的问题。
使用HTML.fragment(r)
时,出现htmlParseStartTag: misplaced <html> tag
错误(以及<body>
和<head>
的类似错误)。
有没有办法阻止它做出这些增加?
一个例子的转换:
之前:
<!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>
使用HTML.fragment
或之后:使用解析
<html>
<head>
<script>
var x = "y";
</script>
</head>
<body>
<div>
Stuff
</div>
</body>
</html>
后
<script>
var x = "y";
</script>
<div>
Stuff
</div>
在这种情况下,我希望它只输出前一节。 (在真正的脚本中,我做了一堆更改)。
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>"
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>]
但是你仍然可以Munge时间的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>"
或者:
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>"
把这些东西在一起,再加上有点狡辩的:
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>"
所以,我会去后,类似的东西。
现在,为什么是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>"
但它变得时髦,如果<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>"
那闻起来像在引入nokogiri的错误给我,因为我还没有看到任何记录该行为的东西。
和Html.fragment一样。如果您提供的HTML包含''标记,它将删除它们。 – CSturgess 2014-09-23 16:08:58
您的编辑仍不能解决问题。
我认为你需要[把它带到Nokogiri作者](https://github.com/sparklemotion/nokogiri),因为它就像一个bug。 – 2014-09-23 17:32:45
你可以通过使用Nokogiri::XML::DocumentFragment
而不是Nokogiri::HTML::DocumentFragment
来解决这个问题。 XML版本不会删除html,head或body标签。
您的“之前”或“之后”部分没有任何地方显示您要替换的标签。相反,它看起来像是在问两个不同的问题。 – 2014-09-23 16:46:43
更换标签是一个不同的问题,我已经解决了一个问题。现在我只关注停止添加doctype标签。 tmpl_var与这个问题无关,我只是把它作为直接拷贝到我如何将文件读入Nokogiri中,以防直接使用String来代替文件。 – CSturgess 2014-09-23 16:49:44
如果temple_var的东西不相关,那么你甚至不应该记录或提及它,因为它是[红鲱鱼](http://en.wikipedia.org/wiki/Red_herring)。 – 2014-09-23 17:14:20