'How do I loop through XML using Nokogiri to add certain parts to an array?
I have this as my XML:
<systems>
<system number="2" >
<lists>
<list critical="user" access="remote"></list>
<list critical="root" access="local"></list>
</lists>
<os system="linux" basebox="AddBaseBox" ></os>
<networks>
<network name="homeonly" ></network>
<network name="homeonly2"></network>
</networks>
</system>
</systems>
I want to add them to an array so I wrote this:
require 'nokogiri'
doc = Nokogiri::XML(File.open("boxesconfig.xml"))
doc.search('//systems/system').each do |system|
list = []
networks = []
systemNumber = system.at('@number').text
os = system.at('//os/@system').text
base = system.at('//os/@basebox').text
list << { "critical" => system.at('//lists/list/@critical').text, "access" => system.at('//lists/list/@access').text}
networks << { "network" => system.at('//networks/network/@name').text}
puts list
puts systemNumber
puts os
puts networks
end
The output I receive is:
{"critical"=>"user", "access"=>"remote"}
2
linux
{"network"=>"homeonly"}
I want to have multiple lists and multiple networks displayed in the array. What am I doing wrong?
The output I want is:
{"critical"=>"user", "access"=>"remote"}
{"root"=>"user", "access"=>"local"}
2
linux
{"network"=>"homeonly"}
{"network"=>"homeonly2"}
Solution 1:[1]
Nokogiri allows you to access the XML using CSS selectors. When your selectors match more than one thing, Nokogiri returns an array of those things. Here, we are using Ruby's Array#collect
method to return a new array of items based on what the block returns:
lists = system.css('lists list').collect do |list|
{ 'critical' => list['critical'], 'access' => list['access'] }
end
networks = system.css('networks network').collect do |network|
{ 'network' => network['name'] }
end
This should give you the output you are looking for.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | the Tin Man |