jaca
jaca

Reputation: 21

Creating Ruby Hash from XML

I have an XML doc that looks like this (and contains hundreds of these entries):

<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 is a hash that I will use as a basis for a dynamic ansible inventory, and has a structure as on the Ansible website:

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

I'm trying to use Nokogiri to retrieve the hostname from the XML doc, and add it to ansible_hash. I would like to have each of the hostnames to be appended to the array under the "hosts" key. How can I achieve this?

When I do this,

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

the entry under "all" => {"hosts" => []} only has the last one like this:

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

Upvotes: 2

Views: 120

Answers (1)

halfelf
halfelf

Reputation: 10087

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

The reason your code not working:

You're trying to merge two hashes with a same key hosts in each block, and the latter one's k/v will overwrite the previous one.

The behavior you need is to append something into an array, so just focus on it and forget about merge hashes.

Upvotes: 5

Related Questions