如何在Nokogiri中使用XPath从基于Tagname的节点集中选择单个元素



给定以下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"的两个元素,然后对每个元素进行操作。

Nokogiri使用Xpath可以很容易地实现第一个查询表达式,如:

price_xml = doc_xml.xpath('Container/Set/*[contains(name(), "Cover")]')

我已经选择了Set中的所有元素(使用*),然后使用了Xpath表达式函数:

包含,以便指定名称中必须包含Adult。这将在Nodeset中返回两个Nokogiri XML节点。

然后,我想做的是根据标记名中的模式选择其中一个元素——使用我最喜欢的工具Xpath。

但我就是无法让Nokogiri给我,几个解决方案最终选择了比我想要的1元素更多的元素。(因为节点集中的节点仍然包含与其父节点的关系)

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

尝试以下操作:

node_xml.at_xpath('./self::*[not(contains(name(), "Recommended"))]')
node_xml.at_xpath('./self::*[contains(name(), "Recommended")]')

并考虑在迭代中使用变量而不是常量。

或者您可以生成节点名称:

songtypes = ['Cover', 'Original', 'Duet', 'Group']
songtypes.each do |st|
  regular = doc.at_xpath("Container/Set/#{st}Song")
  recommended = doc.at_xpath("Container/Set/Recommended#{st}Song")
end

相关内容

  • 没有找到相关文章

最新更新