将XML分配给Ruby类出错
我将XPath搜索的结果分配给Ruby对象,但该对象似乎可以访问整个原始文档,而不仅仅是我分配给它的内容 这是我所经历的一个简化示例:将XML分配给Ruby类出错,ruby,xml,xpath,nokogiri,Ruby,Xml,Xpath,Nokogiri,我将XPath搜索的结果分配给Ruby对象,但该对象似乎可以访问整个原始文档,而不仅仅是我分配给它的内容 这是我所经历的一个简化示例: <message> <person> <name>Joe</name> <organs> <heart>yes</heart> <lungs>yes</lungs> <ears>ye
<message>
<person>
<name>Joe</name>
<organs>
<heart>yes</heart>
<lungs>yes</lungs>
<ears>yes</ears>
</organs>
</person>
<person>
<name>Jim</name>
<organs>
<heart>yes</heart>
<lungs>no</lungs>
<ears>yes</ears>
</organs>
</person>
<person>
<name>Fred</name>
<organs>
<heart>yes</heart>
<lungs>maybe</lungs>
<ears>yes</ears>
</organs>
</person>
</message>
然后,处理消息并将“persons”分配给Person类并执行进一步处理的代码:
message = doc.xpath("message")
message.xpath('person').each do |p|
prsn = Person.new(p)
queue.push("person" => prsn)
end
loop ...
work - queue.pop
per = work['person']
lungs = per.get_lungs
end
问题是,
lungs
总是“是”。在get_
函数中,实际上可以循环原始消息中的所有值,即使Person对象应该只包含消息中的一个Person部分 每个文档节点仍然可以访问整个文档(请参见)。
即使看起来您只传递了一个person
节点,该节点仍然引用整个文档
而且,/
,所以
不依赖于@person
,始终返回第一个lung
。您还可以使用xpath.first代替
只需删除/
,它就可以工作了:
require 'nokogiri'
doc = Nokogiri::XML(message)
doc.xpath('//person').each do |person|
p person.at_xpath("organs/lungs").content
end
它输出:
"yes"
"no"
"maybe"
谢谢你的回答。但我还是很困惑。给定此代码:code
message.xpath('person')。每个do | p | prsn=person.new(p)queue.push(“person”=>prsn)endcode
-当仅将prsn分配给对象时,每个“prsn”如何能看到整个消息?更新<代码>prsn.文档
仍然可以从您的Person实例访问。谢谢!我不能说我完全理解为什么会这样,但你的解决方案奏效了。我的代表投票给你的答案太小,无法显示。你不明白什么?很少需要使用xpath
,css
,at_css
或at_xpath
,而通常搜索或at
就足够了。Nokogiri通常能够确定选择器是CSS还是XPath。在编写Nokogiri代码的几年中,我只需使用显式方法名一次。
require 'nokogiri'
doc = Nokogiri::XML(message)
doc.xpath('//person').each do |person|
p person.at_xpath("organs/lungs").content
end
"yes"
"no"
"maybe"