Nokogiri 并从两个项目创建散列 - 错误检索全部为字符串

Nokogiri and creating a hash from two items - Error retrieves all as string

我正在尝试从带有 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>

以下是我的解决方法:

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. 合并结果以生成您的散列。

请注意,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