0

我正在尝试编写一个脚本,该脚本将遍历 Ruby 中的 CSV 文件,该文件将生成一个多级无序列表。

我现在拥有的代码并没有切断<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" 
4

1 回答 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
于 2013-10-11T20:21:00.050 回答