'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