2

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" => {}
}

1 Answer 1

5
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.

Sign up to request clarification or add additional context in comments.

3 Comments

Shouldn't it be ansible_hash['all']['hosts'] = [entry.inner_text]?
@iGian the << appends each host in the block, = would overwrite each and leave only the last entry.
any reason we don't just go with ansible_hash['all']['hosts'] = xml_doc.xpath("//entry//hostname").map(&:inner_text)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.