0

次のような構造の大きなローカル XML ファイル (24 GB) があります。

<id>****</id>
<url> ****</url> (several times within an id...)

次のような結果が必要です。

id1;url1
id1;url2
id1;url3
id2;url4
....

ファイル全体をメモリにロードできないため、SAX パーサーまたはリーダーのいずれかで Nokigiri を使用したかったのです。Ruby Rake タスクを使用してコードを実行しています。

SAXを使用した私のコードは次のとおりです。

task :fetch_saxxml => :environment do

  require 'nokogiri'
  require 'open-uri'

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

    def initialize
      @is_name = false
    end

    def start_element name, attributes = []
      @is_name = name.eql?("id")
    end

    def characters string
      string.strip!
      if @is_name and !string.empty?
        puts "ID: #{string}"
      end
    end

    def end_document
      puts "the document has ended"
    end

  end

  parser = Nokogiri::XML::SAX::Parser.new(MyDocument.new)
  parser.parse_file('/path_to_my_file.xml')

end

ファイル内の ID を取得するにはそれで問題ありませんが、各 ID ノード内の URL も取得する必要があります。

そのコード内に「each do」のようなものを入れて、URL をフェッチし、上記のような出力を得るにはどうすればよいですか? または、「キャラクター」内で複数のアクションを呼び出すことは可能ですか?

4

1 に答える 1

0

実際、これは複数のノードが発生したときにそれらを解析するソリューションです。SAX パーサーの問題は、"&" などの特殊文字を処理する方法を見つけなければならないことですが、それはまた別の話です。

これが私のコードです:

class MyDoc < Nokogiri::XML::SAX::Document
  def start_element name, attrs = []
    @inside_content = true if name == 'yourvalue'
    @current_element = name
  end


  def characters str

    if @current_element == 'your_1st subnode'

    elsif @current_element == 'your 2nd subnode'


    end
    puts "#{@current_element} - #{str}" if @inside_content && %w{your_subnodes here}.include?(@current_element)
  end

  def end_element name
    @inside_content = false if name == 'yourvalue'
    @current_element = nil
  end

end

parser = Nokogiri::XML::SAX::Parser.new(MyDoc.new)
parser.parse_file('/path_to_your.xml')

end
于 2013-02-07T11:32:49.507 に答える