首页 > 解决方案 > 从 XML 创建 Ruby 哈希

问题描述

我有一个看起来像这样的 XML 文档(并且包含数百个这样的条目):

<entry name="entryname">
  <serial>1234567</serial>
  <hostname>host1</hostname>
  <ip-address>100.200.300.400</ip-address>
  <mac-address>00-00-00-00</mac-address>
</entry>

ansible_hash是一个哈希值,我将用作动态 ansible 库存的基础,其结构与 Ansible 网站上的结构相同:

ansible_hash = {
  "_meta" => {"hostvars" => {}},
  "all" => {
    "children" => ["ungrouped"]
  },
  "ungrouped" => {}
}

我正在尝试使用 Nokogiri 从 XML 文档中检索主机名,并将其添加到ansible_hash. 我想让每个主机名都附加到"hosts"键下的数组中。我怎样才能做到这一点?

当我这样做时,

xml_doc = Nokogiri::XML(File.open("file.xml", "r"))
xml_doc.xpath("//entry//hostname").each do |entry|
  ansible_hash["all"] = ansible_hash["all"].merge("hosts" => ["#{entry.inner_text}"])
end

下面的条目"all" => {"hosts" => []}只有最后一个是这样的:

{
  "_meta" => {"hostvars"=>{}},
  "all" => {
    "children" => ["ungrouped"],
    "hosts" => ["host200"]
  },
  "ungrouped" => {}
}

标签: rubyhash

解决方案


ansible_hash['all']['hosts'] = []
xml_doc.xpath("//entry//hostname").each do |entry|
  ansible_hash['all']['hosts'] << entry.inner_text
end

您的代码不起作用的原因:

hosts您正在尝试在块中合并两个具有相同键的哈希each,而后者的 k/v 将覆盖前一个。

您需要的行为是将某些内容附加到数组中,因此只需关注它并忘记合并哈希。


推荐阅读