Вот как я бы это сделал в Нокогири:
require 'nokogiri'
xml = '<objects><object uid="0" /><object uid="1" /><object uid="2" /></objects>'
doc = Nokogiri::XML(xml)
objects_by_uid = doc.search('//object[@uid="2" or @uid="1"]').sort_by { |n| n['uid'].to_i }.reverse
puts objects_by_uid
Запуск, который выводит:
<object uid="2"/>
<object uid="1"/>
Альтернативой поиску будет:
objects_by_uid = doc.search('//object[@uid="2" or @uid="1"]').sort { |a,b| b['uid'].to_i <=> a['uid'].to_i }
, если вам не нравится использовать sort_by
с reverse
.
XPath полезен для поиска и извлечения узлов, но часто фильтрация, которую мы хотим сделать, становится слишком сложной в аксессоре, поэтому я позволяю языку делать это, будь то Ruby, Perl или Python. То, где я размещаю логику фильтрации, основано на том, насколько велик набор данных XML и есть ли много различных значений uid
, которые я хочу получить. Иногда имеет смысл разрешить движку XPath выполнять тяжелую работу, в других случаях проще позволить XPath захватить все узлы object
и выполнить фильтрацию на языке вызова.