Как я могу перебрать CSV-файл в RUBY, чтобы создать неупорядоченный список HTML?

0

Я пытаюсь написать сценарий, который будет проходить через CSV файл в Ruby, который будет создавать многоуровневый неупорядоченный список.

Код, который у меня есть, не отсекает <ul> в правильных местах. Выход только начинается на новых уровнях.

Вот код Ruby:

require 'csv'

col_data = [] 
CSV.foreach("primary_NAICS_code.txt") {|row| col_data << row} 

begin
  file = File.open("primary_NAICS_code.html", "w")
  file.write("<ul>\n")
  depth = 1
  col_data.each do |row|
    indentation, (text,*) = row.slice_before(String).to_a

    if indentation.length > depth 
      file.write("<ul>\n")
    elsif indentation.length < depth 
      file.write("</ul>\n")
    end

    if text.index(/^\d{2}[:]/)
      file.write("<li>" +text+ "</li></ul>\n")
    else  
      file.write("<li>" +text+ "</li>\n")
    end
    depth = indentation.length

  end
  file.write("</ul>\n")
rescue IOError => e
  puts e
ensure
  file.close unless file == nil
end

Это результат, который я получаю:

11: Agriculture, Forestry, Fishing and Hunting
  111: Crop Production
    111110: Soybean Farming
    111120: Oilseed (except Soybean) Farming
    111130: Dry Pea and Bean Farming
    .
    .
    .
  112: Animal Production
    112111: Beef Cattle Ranching and Farming
    112112: Cattle Feedlots
    .
    .
    .
  21: Mining<~~(there should be a </ul> here)
   211: Oil and Gas Extraction
     211111: Crude Petroleum and Natural Gas Extraction
     211112: Natural Gas Liquid Extraction

И файл CSV:

,"11: Agriculture, Forestry, Fishing and Hunting",,
,,"111: Crop Production",
,,,"111110: Soybean Farming"
,,,"111120: Oilseed (except Soybean) Farming"
,,,"111130: Dry Pea and Bean Farming"
,,,"111140: Wheat Farming"
,,,"111150: Corn Farming"
,,,"111160: Rice Farming"
,,,"111191: Oilseed and Grain Combination Farming"
,,,"111199: All Other Grain Farming"
,,,"111211: Potato Farming"
,,,"111219: Other Vegetable (except Potato) and Melon Farming"
,,"112: Animal Production",
,,,"112111: Beef Cattle Ranching and Farming"
,,,"112112: Cattle Feedlots"
,,,"112120: Dairy Cattle and Milk Production"
,,,"112130: Dual-Purpose Cattle Ranching and Farming"
,,,"112210: Hog and Pig Farming"
,,"113: Forestry and Logging",
,,,"113110: Timber Tract Operations"
,,,"113210: Forest Nurseries and Gathering of Forest Products"
,,,"113310: Logging"
,,"114: Fishing, Hunting and Trapping",
,,,"114111: Finfish Fishing"
,,,"114112: Shellfish Fishing"
,,,"114119: Other Marine Fishing"
,,,"114210: Hunting and Trapping"
,,"115: Support Activities for Agriculture and Forestry", 
,"21: Mining",,
,,"211: Oil and Gas Extraction",
,,,"211111: Crude Petroleum and Natural Gas Extraction"
,,,"211112: Natural Gas Liquid Extraction"
,,"212: Mining (except Oil and Gas)",
.
.
.
,"54: Professional, Scientific, and Technical Services",,
,,"541: Professional, Scientific, and Technical Services",
,,,"541110: Offices of Lawyers" 
  • 0
    Было бы здорово увидеть структуру входного файла.
  • 0
    Только что отредактировал вопрос.
Теги:
csv

1 ответ

1
require 'csv'

CSV_FILE  = 'data.csv'
HTML_FILE = 'data.html'

# helper class for nodes in a tree
class Node < Struct.new(:parent, :text, :children)

  def initialize(parent, text)
    super
    self.children = []
    parent.children << self   if parent
    self
  end

  def level
    root? ? 0 : parent.level + 1
  end

  def to_html
    "".tap do |html|
      html << "#{tabs(level)}<li>#{text}"                           unless root?
      html << "#{tabs(level)}<ul>#{children.map(&:to_html).join}</ul>"  if children.any?
      html << "</li>"                                               unless root?
    end
  end

private

  def root?
    parent.nil?
  end

  def tabs(level)
    "\n" + "\t" * level
  end

end

# init tree
tree = Node.new(nil, :root)
node = tree

# process csv file
CSV.read(CSV_FILE).map do |row|
  levels, (text, _) = row.slice_before(String).to_a
  level = levels.size

  parent = node               if level >  node.level
  parent = node.parent        if level == node.level
  parent = node.parent.parent if level <  node.level

  node = Node.new(parent, text)
end

# write output file
File.open(HTML_FILE, 'w') do |file|
  file << "<!DOCTYPE HTML><html><head><title>CSV</title></head><body>"
  file << tree.to_html
  file << "</body></html>"
end
  • 0
    И у вас, и у Железного человека есть отличные ответы. Структуры UL LI по-прежнему неуместны и неправильно их форматируют. Я выберу этот код, так как будет проще написать другой код, чтобы получить окончательное решение. Спасибо большое за вашу помощь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню