0

すべてのハッシュ値を保存したい CSV があります。nokogiri sax を使用して xml ドキュメントを解析し、CSV に保存しています。

最初のxmlファイルを解析して保存しますが、2番目のファイルの解析を開始すると停止し、エラーは次のようになります:

エラー: NoMethodError: undefined method <<' for nil:NilClass`

@infodata[:titles] << @content で nil エラーが発生しています

サックスパーサー:

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 つの xml ファイル: https://gist.github.com/2378898 https://gist.github.com/2378901 https://gist.github.com/2378904

4

1 に答える 1

0

あなたはこれをやっています:

csv = CSV.generate_line(HEADERS.map {|h| @infodata[h] })
csv << "\n"

何らかの理由でがnilCSV.generate_line(HEADERS.map {|h| @infodata[h] })を返す場合、定義されていない nil オブジェクトに対して << メソッドを使用しようとしています。

csvが nil の場合に"\n" を追加しないように、いくつかの条件を追加することをお勧めします。

于 2012-04-14T22:26:53.187 に答える