我将XPath搜索的结果分配给Ruby对象,但该对象似乎可以访问整个原始文档,而不仅仅是我分配的内容。
这是我正在经历的一个简化示例:
<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>
然后我有一个专门用于保存部分信息的课程:
class Person
attr_accessor :person
def initialize(info)
@person = info
end
def get_lungs
return @person.xpath("//organs/lungs").first.content
end
end
然后是处理消息并将“人员”分配给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_lungs
函数中,实际上可以循环遍历原始消息中的所有值,即使Person对象应该只包含消息中的一个人部分。
答案 0 :(得分:1)
每个文档节点仍然可以访问整个文档(请参阅documentation)。
即使您只是传递person
节点,该节点仍然引用整个文档!
另外,//
scans the whole document,所以
@person.xpath("//organs/lungs").first
不依赖@person
并始终返回第一个lung
。您也可以使用at_xpath
代替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"