Reputation: 6454
Trying to get my head around Nokogiri and XPath, and hoping you can help explain this behaviour. This code:
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
Gives this output:
<peas>
<color>"green"</color>
</peas>
"green"
"green"
"yellow"
<peas>
<color>"yellow"</color>
</peas>
"yellow"
"green"
"yellow"
How does puts p.xpath('//color/text()')
end up retrieving both green and yellow, while p only contains one or the other?
Upvotes: 0
Views: 491
Reputation: 3209
Since it's breaking down the <peas>
nodes into p, and iterating through them, it is first displaying the node itself
<peas>
<color>"green"</color>
</peas>
and
<peas>
<color>"yellow"</color>
</peas>
and then the <color>
node's text of each p as well.
THEN, we get to //color/text()
, and '//
' says start over at the root, and get all <color>
nodes, and the text()
associated with them, which is why you get both Green and Yellow colors, even while iterating through each <peas>
node separately.
So for another example, if we had iterated to the node veg/peas[color='green']
, and then said find //peas
, we would get back both <peas>
nodes for yellow and green.
color/text()
says "start from current node, and grab me the text of the child node <color>
"
and //color/text()
says "give me the text of all <color>
nodes in the XML, regardless of current location"
Let me know if I need to clarify anything...
Upvotes: 1