हैश को सीएसवी में परिवर्तित करें - रूबी, सीएसवी, हैश, नोकोगिरी, सैक्सपार्सर

मेरे पास एक सीएसवी है कि मैं अपने सभी हैश मानों को सहेजना चाहता हूं। मैं एक एक्सएमएल दस्तावेज़ को पार्स करने के लिए nokogiri sax का उपयोग कर रहा हूं और फिर इसे एक CSV में सहेज रहा हूं।

सैक्स पार्सर:

require "rubygems"
require "nokogiri"
require "csv"

class MyDocument < Nokogiri::XML::SAX::Document

HEADERS = [ :titles, :identifier, :typeOfLevel, :typeOfResponsibleBody,
:type, :exact, :degree, :academic, :code, :text ]

def initialize
@infodata = {}
@infodata[:titles] = Array.new([])
end

def start_element(name, attrs)
@attrs = attrs
@content = ""
end
def end_element(name)
if name == "title"
Hash[@attrs]["xml:lang"]
@infodata[:titles] << @content
@content = nil
end
if name == "identifier"
@infodata[:identifier] = @content
@content = nil
end
if name == "typeOfLevel"
@infodata[:typeOfLevel] = @content
@content = nil
end
if name == "typeOfResponsibleBody"
@infodata[:typeOfResponsibleBody] = @content
@content = nil
end
if name == "type"
@infodata[:type] = @content
@content = nil
end
if name == "exact"
@infodata[:exact] = @content
@content = nil
end
if name == "degree"
@infodata[:degree] = @content
@content = nil
end
if name == "academic"
@infodata[:academic] = @content
@content = nil
end
if name == "code"
Hash[@attrs]["source="vhs""]
@infodata[:code] = @content
@content = nil
end
if name == "ct:text"
@infodata[:beskrivning] = @content
@content = nil
end
end
def characters(string)
@content << string if @content
end
def cdata_block(string)
characters(string)
end
def end_document
File.open("infodata.csv", "ab") do |f|
csv = CSV.generate_line(HEADERS.map {|h| @infodata[h] })
csv << "n"
f.write(csv)
end
end
end

फ़ोल्डर में स्टोर की जाने वाली प्रत्येक फ़ाइल के लिए नया ऑब्जेक्ट बनाना (47.000xml फ़ाइलें):

parser = Nokogiri::XML::SAX::Parser.new(MyDocument.new)
counter = 0

Dir.glob("/Users/macbookpro/Desktop/sax/info_xml/*.xml") do |item|
parser.parse(File.open(item, "rb"))
counter += 1
puts "Writing file nr: #{counter}"
end

समस्या: मुझे मूल्यों के हर नए सेट के लिए एक नई लाइन नहीं मिलती है। कोई विचार?

कोड की कोशिश करने के लिए 3 एक्सएमएल फाइलें: https://gist.github.com/2378898 https://gist.github.com/2378901 https://gist.github.com/2378904

उत्तर:

जवाब के लिए 3 № 1

आपको "ए" मोड का उपयोग करके फ़ाइल खोलनी होगी ("डब्ल्यू" वाली फाइल खोलना किसी भी पिछली सामग्री को साफ़ करता है)।

सीएसवी ऑब्जेक्ट में एक सरणी जोड़ना होगास्वचालित रूप से न्यूलाइन डालें। हैश # मान मानों की एक सरणी देता है, लेकिन आदेश को मजबूर करना सुरक्षित होगा। सरणी को फ़्लैटन करने से संभावित रूप से गलत हस्ताक्षर किए गए कॉलम (उदा। [[शीर्षक 1, शीर्षक 2], "अन्य-मूल्य"] का परिणाम होगा [: शीर्षक 1,: शीर्षक 2, "अन्य-मूल्य"])। इस तरह कुछ कोशिश करें:

HEADERS = [:titles, :identifier, ...]

def end_document
# with ruby 1.8.7
File.open("infodata.csv", "ab") do |f|
csv = CSV.generate_line(HEADERS.map { |h| @infodata[h] })
csv << "n"
f.write(csv)
end
# with ruby 1.9.x
CSV.open("infodata.csv", "ab") do |csv|
csv << HEADERS.map { |h| @infodata[h] }
end
end

उपर्युक्त परिवर्तन निम्नलिखित निष्पादित करके सत्यापित किया जा सकता है:

require "csv"

class CsvAppender

HEADERS = [ :titles, :identifier, :typeOfLevel, :typeOfResponsibleBody, :type,
:exact, :degree, :academic, :code, :text ]

def initialize
@infodata = { :titles => ["t1", "t2"], :identifier => 0 }
end

def end_document
@infodata[:identifier] += 1

# with ruby 1.8.7
File.open("infodata.csv", "ab") do |f|
csv = CSV.generate_line(HEADERS.map { |h| @infodata[h] })
csv << "n"
f.write(csv)
end
# with ruby 1.9.x
#CSV.open("infodata.csv", "ab") do |csv|
#  csv << HEADERS.map { |h| @infodata[h] }
#end
end

end

appender = CsvAppender.new

3.times do
appender.end_document
end

File.read("infodata.csv").split("n").each do |line|
puts line
end

उपरोक्त चलाने के बाद infodata.csv फ़ाइल में निम्न शामिल होंगे:

"[""t1"", ""t2""]",1,,,,,,,,
"[""t1"", ""t2""]",2,,,,,,,,
"[""t1"", ""t2""]",3,,,,,,,,

उत्तर № 2 के लिए 1

मुझे लगता है कि आपको एक अतिरिक्त पाश की जरूरत है। कुछ समान है

CSV.open("infodata.csv", "wb") do |csv|
csv << @infodata.keys
@infodata.each do |key, value|
csv << value
end
end

संबंधित सवाल
सबसे लोकप्रिय