title: How to use XPath with Nokogiri to select a single element from a Nodeset based on Tagname
body: <p>Given the following XML, </p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;Container&gt;
  &lt;Set &gt;
  &lt;RecommendedCoverSong&gt;Hurt by NiN - Johnny Cash&lt;/RecommendedCoverSong&gt;
  &lt;RecommendedOriginalSong&gt;She Like Electric by Smoosh&lt;/RecommendedOriginalSong&gt;
  &lt;RecommendedDuetSong&gt;Portland by Jack White and Loretta Lynn&lt;/RecommendedDuetSong&gt;
  &lt;RecommendedGroupSong&gt;SoS by Abba&lt;/RecommendedGroupSong&gt;
  &lt;CoverSong&gt;Kangaroo  by Big Star  - This Mortal Coil&lt;/CoverSong&gt;
  &lt;OriginalSong&gt;Pick up the Change by Wilco&lt;/OriginalSong&gt;
  &lt;DuetSong&gt;I am the Cosmos by Pete Yorn and Scarlett Johansen&lt;/DuetSong&gt;
  &lt;GroupSong&gt;Kitties Never Rest by Rex or Regina&lt;/GroupSong&gt;
  &lt;/Set&gt;
  &lt;/Container&gt;
  </code></pre>
  
  <p>I'd like to grab two elements that include "Cover" in the tag, and then operate on each of them.</p>
  
  <p>Nokogiri's use of Xpath easily allows the first query expression like so:</p>
  
  <p><code>price_xml = doc_xml.xpath('Container/Set/*[contains(name(), "Cover")]')</code></p>
  
  <p>I've selected all the elements (using *) in Set, and then used an Xpath Expression function:</p>
  
  <p>contains, in order to specify that Adult must be in the name.  This returns two Nokogiri XML Nodes in Nodeset.</p>
  
  <p>What I wanted to do was then select one of these elements based on a pattern in the tagname use my favorite tool, Xpath.</p>
  
  <p>But I just couldn't get Nokogiri to give it to me, and several solutions ending up selecting way more than the 1 element I wanted. (Because the nodes in the Nodeset still contain relationships with their parents)</p>
  
  <pre class="lang-ruby prettyprint-override"><code>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
  </code></pre>
  
  <p><a href="https://gist.github.com/1579343" rel="nofollow">https://gist.github.com/1579343</a></p>