Использование elements = doc.search('//[@box and not(ancestor::@box)]')
неверно.
Используйте elements = doc.at('//div[@box]')
, который найдет первое вхождение.
Я бы рекомендовал использовать Nokogiri вместо Hpricot. Nokogiri хорошо поддерживается, очень гибкий и надежный.
РЕДАКТИРОВАТЬ: Добавлено, потому что оригинальный вопрос изменился:
Спасибо, что сработало отлично, за исключением того, что я забыл упомянуть, что хочу вернуть несколько внешних элементов. Извините, я обновил вопрос. Я рассмотрю Nokogiri дальше, я не выбрал его изначально, потому что Hpricot казался более доступным.
Помните, что XPath действует как доступ к файлу в каталоге в его самой простой форме, поэтому вы можете развернуть его и искать в "подкаталогах". Если вам нужны только внешние теги <div>
, то загляните внутрь уровня <body>
и не дальше:
doc.search('/html/body/div')
или, если у вас есть целые div
метки вместе с целями:
doc.search('/html/body/div[@box]')
Относительно Hpricot, кажущегося более доступным:
Nokogiri реализует расширенный набор аксессоров Hpricot, что позволяет вам использовать его в большинстве случаев. Он поддерживает XPath и CSS-аксессоры, предоставляя более интуитивно понятные способы получения данных, если вы живете в CSS и HTML и не пользуетесь XPath. Кроме того, есть много способов найти желаемую цель:
doc.search('body > div[box]')
(doc / 'body > div[box]')
doc.css('body > div[box]')
Nokogiri также поддерживает синоним at
и %
, найденный в Hpricot, наряду с css_at
, если вы хотите только первое появление чего-либо.
Я начал использовать Nokogiri после того, как столкнулся с некоторыми ситуациями, когда Hpricot взорвался, потому что он не мог обрабатывать неправильно сформированные новостные ленты в дикой природе.