Ruby 使用Nokogiri解析HTML文件中的多个列表

Ruby 使用Nokogiri解析HTML文件中的多个列表,ruby,hash,html-parsing,nokogiri,Ruby,Hash,Html Parsing,Nokogiri,我正在尝试学习使用Ruby编写脚本,这是我的第一个问题 我有一个HTML文件,其中包含各州及其城市。我需要能够在Ruby代码中访问城市并知道它们属于哪个州,因此我计划解析HTML并为每个城市创建一个哈希,如下所示:{New York=>New York city}。 我正在尝试使用Nokogiri,我正在学习 <h4>State</h4> <ul> <li>city</li> <li>city<

我正在尝试学习使用Ruby编写脚本,这是我的第一个问题

我有一个HTML文件,其中包含各州及其城市。我需要能够在Ruby代码中访问城市并知道它们属于哪个州,因此我计划解析HTML并为每个城市创建一个哈希,如下所示:{New York=>New York city}。

我正在尝试使用Nokogiri,我正在学习

  <h4>State</h4>
  <ul>
    <li>city</li>
    <li>city</li>
    <li>city</li>
  </ul>
  <h4>State</h4>
  <ul>
    <li>city</li>
    <li>city</li>
    <li>city</li>
  </ul>
  <h4>State</h4>
  <ul>
    <li>city</li>
    <li>city</li>
    <li>city</li>
  </ul>
这实际上没有什么帮助;我需要弄清楚如何让Nokogiri将每个列表的元素解析为包含城市及其州的哈希。我不知道如何在完成一个州的城市列表时进行循环中断,并为下一个州的城市列表创建一组新的
哈希值

我想我必须为每个列表元素创建一个
hash
,并将该列表的
h4
标记的文本存储在每个
hash
中,这样我就知道该城市属于哪个州。我不知道该怎么做


请随意提供一些关于重构我所得到的东西的建议,因为我知道它可以做得更好。

XPath选择器可以在这里帮助您

states = doc.css('li').map do |city|
  state = city.xpath('../preceding-sibling::h4[1]')
  [city.text, state.text]
end.to_h

#=> {'city' => 'State', ...}
这会抓住所有的
li
城市元素,然后追溯到它们的状态。(XPath的内容如下:
=上一级,
前面的同级::h4
=前面的
h4
元素,
[1]
=第一个这样的元素)

关于您的代码的一些注释:在Ruby中,您不需要初始化数组,并且使用像
map
这样的方法,您永远不需要在循环中跟踪索引变量


请注意,最后的
to_h
仅在Ruby 2.1或更高版本中有效

谢谢,工作很好。是的,我认为我没有使用正确的迭代类型。谢谢你的建议。
states = doc.css('li').map do |city|
  state = city.xpath('../preceding-sibling::h4[1]')
  [city.text, state.text]
end.to_h

#=> {'city' => 'State', ...}