Nokogiri并从两个项目创建哈希 - Error将全部检索为字符串

时间:2015-02-09 00:59:59

标签: ruby hash nokogiri

我正在尝试使用来自Nokogiri的xml文件的九个响应来检索两个元素。检索本身并不难:

number = @doc.xpath('//Race/@RaceNumber').text
# => "123456789"

但它选择它作为一个字符串。这是另一个简化的简化:

name = @doc.css('NameRaceFull')
# => [#<Nokogiri::XML::Element:0x1775154 name="NameRaceFull" attributes=[#<Nokogiri::XML::Attr:0x1774448 name="StakesGroupId" value="346">] 

我的目标是为每个数字和名称

创建一个哈希等
{ 1 => "Greenland Australia Maribyrnong Trial Stakes" }

但是检索将它全部拉成字符串,我怎么能让它工作?

我的解决方案是创建两个数组,然后执行Hash[number.zip(name)],但如果可以一次性完成,那就太棒了。

@doc.xpath('//Race/@RaceNumber').text.each do |name|
  arr << name
end
# => NoMethodError: undefined method `each' for "123456789":String

我从中得到这个XML的示例部分就是这个。

<Race RaceCode="5038498" CurrentRaceStage="Results" RaceNumber="1">
      <NameRaceFull StakesGroupId="346">Greenland Australia Maribyrnong Trial Stakes</NameRaceFull>

1 个答案:

答案 0 :(得分:1)

以下是我将如何解决它:

hash = Hash[doc.xpath('//Race').map{|race|
  [race["RaceNumber"].to_i, race.xpath('NameRaceFull').text]
}]

输出哈希:

{1=>"Foo", 2=>"Goo", 3=>"Hoo"}

代码的工作原理如下:

  1. 找到所有Race项并迭代它们。
  2. 每次迭代都会产生一个密钥(即竞赛号码)和一个值(即全名)。
  3. 合并结果以产生哈希值。
  4. 请注意,Ruby提供了多种将项目转换为哈希的方法,您可以按照自己喜欢的方式使用。例如,Hash#[]Array#to_hEnumerable#inject

    这是一个完整的代码示例,为了清晰起见,简化了XML:

    #!/usr/bin/env ruby
    require 'nokogiri'
    
    xml=<<-qqq
    <Races>
    <Race RaceNumber="1"><NameRaceFull>Foo</NameRaceFull></Race>
    <Race RaceNumber="2"><NameRaceFull>Goo</NameRaceFull></Race>
    <Race RaceNumber="3"><NameRaceFull>Hoo</NameRaceFull></Race>
    </Races>
    qqq
    
    doc=Nokogiri.parse(xml)
    
    hash = Hash[doc.xpath('//Race').map{|race|
      [race["RaceNumber"].to_i, race.xpath('NameRaceFull').text]
    }]
    
    p hash