Если вы знаете глубину нужного вам предмета, вы можете сделать это:
p d.at_xpath('//property[@name="animationUrl"][count(ancestor::*) = 1]')
Однако, если вы знаете глубину, тогда, конечно, это легче сделать:
p d.at_xpath('/*/property[@name="animationUrl"]')
Если вы хотите выполнить поиск в ширину, чтобы найти самый мелкий предмет на любой глубине:
Хотя XPath позволяет вам определять глубину элемента (как показано выше), он не позволяет вам сортировать элементы в возвращенном NodeSet (что вам и нужно сделать в чистом XPath). Поэтому нам придется прибегнуть к использованию Ruby для общего случая:
class Nokogiri::XML::Node
def at_shallowest_xpath( path )
xpath(path).sort_by{ |n| n.xpath 'count(ancestor::*)' }.first
end
end
d = Nokogiri::XML xml_source
puts d.at_shallowest_xpath('//property[@name="animationUrl"]')
#=> <property name="animationUrl" value="myanim3"/>
Редактировать : Использование XPath для нахождения глубины, хотя и хитрое, примерно вдвое медленнее (на моей машине с данными этого теста) как запрос Нокогири найти глубину элемент для вас. Вместо этого используйте это:
class Nokogiri::XML::Node
def at_shallowest_xpath( path )
xpath(path).sort_by{ |n| n.ancestors.length }.first
end
end