2012-12-21 37 views
0

试图让我的脑袋围绕Nokogiri和XPath,并希望你能帮助解释这种行为。此代码:Nokogiri:嵌套xpath如何访问外层循环?

data = Nokogiri::XML(%{ 
    <veg> 
    <peas> 
     <color>"green"</color> 
    </peas> 
    <peas> 
     <color>"yellow"</color> 
    </peas> 
    </veg> 
}) 

data.xpath('//peas').each do |p| 
    puts p        
    puts p.xpath('color/text()')   
    puts p.xpath('//color/text()') # output not as expected 
end 

给出了这样的输出:

<peas> 
    <color>"green"</color> 
</peas> 

"green" 

"green" 
"yellow" 

<peas> 
    <color>"yellow"</color> 
</peas> 

"yellow" 

"green" 
"yellow" 

如何放p.xpath('//color/text()')结束了检索绿色和黄色,而p只包含一个或其他?

+1

这是一个常见的XPath新手错误,思考'//节点'实际上意味着'.//节点'。 –

+1

除非你绝对必须了解XPath,否则我建议在Nokogiri中使用CSS。 CSS访问器更简单,大多数情况下更容易阅读。尽管XPath能够进行非常复杂的搜索,所以我将它用于这些特殊场合。尝试'data.search('peas color')。map(&:text)'。 –

+0

@MarkThomas谢谢! –

回答

1

,因为它打破了<peas>节点为P,并通过他们迭代,它首先显示节点本身

<peas> 
    <color>"green"</color> 
</peas> 

<peas> 
    <color>"yellow"</color> 
</peas> 

,然后<color>节点的每个p的文本以及。

然后,我们到//color/text(),和“//”说,从根开始了,并得到所有<color>节点,以及与之相关的text(),这就是为什么你会得到绿色和黄色的颜色,即使通过迭代每个<peas>节点分开。例如,如果我们已经迭代到节点veg/peas[color='green'],然后说找到//peas,我们将返回<peas>节点的黄色和绿色。

color/text()说:“从当前节点开始和我抢子节点<color>的文本” 和//color/text()说:“给我所有<color>节点的文本在XML中,无论当前位置的”

设我知道我是否需要澄清任何东西......