@rda1902

Как правильно создавать большие xml файлы?

Всем привет!)) Появилась задача создать большой xml файл для sphinx, около 40-50мб. Использую nokogiri. В большинстве случаев таск падает с ошибкой NoMemoryError: failed to allocate memory
/usr/local/rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node.rb:686:in `write'
/usr/local/rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node.rb:686:in `native_write_to'
/usr/local/rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node.rb:686:in `write_to'
/usr/local/rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node.rb:618:in `serialize'
/usr/local/rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/builder.rb:346:in `to_xml'


На vps 2gb памяти. Во время формирования xml процесс есть до 1,5gb памяти. Вот код
builder = Nokogiri::XML::Builder.new(:encoding => 'utf-8')
    builder['sphinx'].docset('xmlns:sphinx' => 'http://sphinxsearch.com/') {
      builder.schema {
        builder.field(name: :name, attr: :string)
        builder.field(name: :content, attr: :string)
        builder.field(name: :sender, attr: :string)
        builder.field(name: :recipient, attr: :string)
      }
      SpamMail.includes(:recipient).find_each do |sm|
          content = sm.content
        builder.document(id: sm.id) { |doc|
          doc.parent.default_namespace = ''
          doc.name sm.name
          doc.content content
          doc.sender sm.sender_email
          doc.recipient sm.recipient.email
        }
      end
    }
File.open(File.join(ENV['SPHINX_DIR'],"out_#{Rails.env}.xml"), "w") do |f|
      f.puts xml
    end

Что можете посоветовать для оптимизации?
  • Вопрос задан
  • 616 просмотров
Пригласить эксперта
Ответы на вопрос 2
jbmeerkat
@jbmeerkat
Ruby / Ruby on Rails developer
Думаю для этой цели хорошо подойдет libxml. Nokogiri отличное решение для парсинга файлов, но для построения больших файлов лучше его не использовать.
Ответ написан
Комментировать
viktorvsk
@viktorvsk
Есть два вида XML парсеров\билдеров: DOM и SAX. DOM сначала строит полную древовидную модель документа, после - ее обрабатывает. SAX - обрабатывает поэлементно.

Например, посмотрите варианты здесь:
www.plugingeek.com/categories/xml-parsers-and-buil...
https://www.ruby-toolbox.com/categories/xml_mapping

Хотя, случай у вас настолько простой, вроде как, что вы можете и вручную составлять файл:
- Выбрали записи
- Обрабатываете по одной
- Каждая запись добавляет дописывает файл
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы