Search code examples
rubywatirpage-object-gem

how to format a table using nokogiri as in specified format


I tried using below code but am getting the details like below: Can any one please provide the solution for it.

class HtmlTablePage
    include PageObject

    page_url 'https://www.w3schools.com/html/html_tables.asp'

    table(:table, id: 'customers')

    def get_table_data
        page = Nokogiri::HTML.parse(table_element.html)
        table = page.css('table#customers tbody tr th')
        data = {}
        for i in table do
            data[i.text] = page.css("table#customers tbody tr td").map(&:text)
        end
        p data
    end
end
{"Company"=>["Alfreds Futterkiste", "Maria Anders", "Germany", "Centro comercial Moctezuma", "Francisco Chang", "Mexico", "Ernst Handel", "Roland Mendel", "Austria", "Island Trading", "Helen Bennett", "UK", "Laughing Bacchus Winecellars", "Yoshi Tannamuri", "Canada", "Magazzini Alimentari Riuniti", "Giovanni Rovelli", "Italy"], "Contact"=>["Alfreds Futterkiste", "Maria Anders", "Germany", "Centro comercial Moctezuma", "Francisco Chang", "Mexico", "Ernst Handel", "Roland Mendel", "Austria", "Island Trading", "Helen Bennett", "UK", "Laughing Bacchus Winecellars", "Yoshi Tannamuri", "Canada", "Magazzini Alimentari Riuniti", "Giovanni Rovelli", "Italy"], "Country"=>["Alfreds Futterkiste", "Maria Anders", "Germany", "Centro comercial Moctezuma", "Francisco Chang", "Mexico", "Ernst Handel", "Roland Mendel", "Austria", "Island Trading", "Helen Bennett", "UK", "Laughing Bacchus Winecellars", "Yoshi Tannamuri", "Canada", "Magazzini Alimentari Riuniti", "Giovanni Rovelli", "Italy"]}

But I need like this:

{'Company': ['Alfreds Futterkiste', 'Centro comercial Moctezuma', 'Ernst Handel', 'Island Trading', 'Laughing Bacchus Winecellars', 'Magazzini Alimentari Riuniti'], 'Country': ['Germany', 'Mexico', 'Austria', 'UK', 'Canada', 'Italy'], 'Contact': ['Maria Anders', 'Francisco Chang', 'Roland Mendel', 'Helen Bennett', 'Yoshi Tannamuri', 'Giovanni Rovelli']}

Solution

  • You can collect each row's text as an Array and then use Array#transpose to switch it to columns of data:

    def get_table_data
        page = Nokogiri::HTML.parse(table_element.html)
        trs = page.css('table#customers tr')
        row_texts = trs.map { |tr| tr.css('th', 'td').map(&:text) }
        data = {}
        row_texts.transpose.each { |col_text| data[col_text.shift] = col_text }
        p data
    end