我有一个这样的脚本:
require 'rubygems'
require 'nokogiri'
require 'json'
data = File.read("data.json")
obj = JSON.parse(data)
puts obj.values
@page = Nokogiri::HTML(open("template.panoramatemplate"))
recipename = @page.xpath("//body/h1")
recipename.content = "hello"
puts teachername
我有一个非常基本的HTML文件:
<html>
<head>
<title><* page.title *></title>
</head>
<body>
<h1><* recipe.name *></h1>
<* food name *>
<* food.name *>
<* more values *>
<p><* value *></p>
<* ENDEACH *>
<* ENDEACH *>
</body>
</html>
我看了这一节:http://nokogiri.org/tutorials/modifying_an_html_xml_document.html
第一个例子是改变文本内容。我试着效仿这个例子,但我得到了:
undefined method content= for [#<Nokogiri::XML::Element:0x80d1fb98 name="h1">]:Nokogiri::XML::NodeSet (NoMethodError)
我是否错误地打开了文件?
答案 0 :(得分:3)
有几件事是错的。首先,你要求Nokogiri解析看起来有点像 HTML的东西,但不是。 Nokogiri很聪明,知道不同之处:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<head>
<title><* page.title *></title>
</head>
<body>
<h1><* recipe.name *></h1>
<* food name *>
<* food.name *>
<* more values *>
<p><* value *></p>
<* ENDEACH *>
<* ENDEACH *>
</body>
</html>
EOT
puts doc.to_html
# >> <!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=US-ASCII">
# >> <title></title>
# >> </head>
# >> <body>
# >> <h1></h1>
# >>
# >>
# >>
# >> <p></p>
# >>
# >>
# >> </body>
# >> </html>
注意输出中的块?以下是Nokogiri对HTML的评论:
doc.errors
# => [#<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>,
# #<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>]
因此,除非该模板是有效的HTML,否则您不能指望Nokogiri处理模板。
在删除无效标记并简化HTML后,下一期是:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<h1>foo</h1>
</body>
</html>
EOT
h1 = doc.search('h1')
h1.class # => Nokogiri::XML::NodeSet
h1.respond_to?(:content=) # => false
请注意,使用search
会返回一个不理解content=
的NodeSet。 search
以及css
和xpath
会返回一个NodeSet。你可以遍历返回的NodeSet并处理单个节点,但是,按原样,尝试将相同的内容设置为NodeSet中的一堆节点是不合逻辑的,所以Nokogiri没有&# 39;实现它。
相反:
h1 = doc.at('h1')
h1.class # => Nokogiri::XML::Element
h1.respond_to?(:content=) # => true
h1.content = 'hello'
at
,at_css
和at_xpath
等同于使用search('some selector').first
,这就是他们只返回一个节点的原因。
现在看看DOM:
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >> <body>
# >> <h1>hello</h1>
# >> </body>
# >> </html>
答案 1 :(得分:2)