Учитывая следующий XML,
<Container>
<Set >
<RecommendedCoverSong>Hurt by NiN - Johnny Cash</RecommendedCoverSong>
<RecommendedOriginalSong>She Like Electric by Smoosh</RecommendedOriginalSong>
<RecommendedDuetSong>Portland by Jack White and Loretta Lynn</RecommendedDuetSong>
<RecommendedGroupSong>SoS by Abba</RecommendedGroupSong>
<CoverSong>Kangaroo by Big Star - This Mortal Coil</CoverSong>
<OriginalSong>Pick up the Change by Wilco</OriginalSong>
<DuetSong>I am the Cosmos by Pete Yorn and Scarlett Johansen</DuetSong>
<GroupSong>Kitties Never Rest by Rex or Regina</GroupSong>
</Set>
</Container>
Я бы хотел взять два элемента, которые включают в себя тег «Cover», а затем оперировать каждым из них.
Использование Xpath в Nokogiri легко позволяет первое выражение запроса следующим образом:
price_xml = doc_xml.xpath('Container/Set/*[contains(name(), "Cover")]')
Я выбрал все элементы (используя *) в Set, а затем использовал функцию Xpath Expression:
содержит, чтобы указать, что Adult должен быть в имени. Это возвращает два Nokogiri XML-узла в Nodeset.
Затем я хотел выбрать один из этих элементов на основе шаблона в тэге и использовать мой любимый инструмент Xpath.
Но я просто не мог заставить Нокогири дать его мне, и несколько решений заканчивали тем, что они выбрали больше, чем 1 элемент, который я хотел. (Поскольку узлы в Nodeset все еще содержат отношения с их родителями)
songtypes = ['Cover', 'Original', 'Duet', 'Group']
songtypes.each do |song|
node_xml = doc.xpath('Container/Set/*[contains(name(), "Cover")]')
#I wanted to be able to do the following
#
FavoriteCover = node_xml.xpath('./*[contains(name(), "Recommended")]')
RegularCover = node_xml.xpath('./*[not(contains(name(), "Recommended"))]')
#or
FavoriteCover = node_xml.xpath('*[contains(name(), "Recommended")]')
RegularCover = node_xml.xpath('*[not(contains(name(), "Recommended"))]')
#But instead I had to resort to a Rails solution
RegularCover = node_xml.find{ |node| node.name !~ /Recommended/ }
FavoriteCover = node_xml.find{ |node| node.name =~ /Recommended/ }
#Do something with the songs here
end
https://gist.github.com/1579343