Как привести в порядок искаженный xml в ruby - PullRequest
3 голосов
/ 16 августа 2011

У меня возникли проблемы с уборкой искаженного XML-кода, который я получаю из базы данных SEC edgar .

По какой-то причине они ужасно сформировали xml.Теги, которые содержат любые строки, не закрываются, и они могут содержать другие документы XML или HTML внутри других тегов.Обычно у меня это было Tidy , но это не поддерживается.

Я пытался использовать Nokogiri :: XML :: SAX :: Parser, но это, кажется, душит, потому чтотеги не закрыты.Кажется, он работает нормально, пока не достигнет первого конечного тега, а затем больше не срабатывает.Но он выплевывает правильные символы.

  class Filing < Nokogiri::XML::SAX::Document
    def start_element name, attrs = []
      puts "starting: #{name}"
    end

    def characters str
      puts "chars: #{str}"
    end

    def end_element name
      puts "ending: #{name}"
    end
  end

Кажется, что это был бы лучший вариант, потому что я могу просто проигнорировать другой документ XML или HTML.Кроме того, это имеет смысл, поскольку некоторые из этих документов могут стать достаточно большими, поэтому сохранение всей памяти в памяти, вероятно, не будет работать.

Вот несколько примеров файлов: 1 2 3

Я начинаю думать, что мне просто нужно написать свой собственный анализатор

1 Ответ

3 голосов
/ 16 августа 2011

Обычный DOM-режим Nokogiri способен автоматически исправлять XML-код, чтобы он был синтаксически верным, или вполне обоснованным. Это иногда сбивает с толку и смещает закрывающие теги, но вы можете предварительно обработать файл, чтобы при необходимости подтолкнуть его в правильном направлении.

Я сохранил XML # 1 в документе и загрузил его:

require 'nokogiri'

doc = ''
File.open('./test.xml') do |fi|
  doc = Nokogiri::XML(fi)
end

puts doc.to_xml

После анализа вы можете проверить метод errors экземпляра Nokogiri :: XML :: Document в экземпляре, чтобы увидеть, какие ошибки были сгенерированы, для извращенного удовольствия.

doc.errors

Если использование модели DOM компании Nokogiri недостаточно хорошо, вы рассматривали вопрос об использовании XMLLint для предварительной обработки и очистки данных, генерируя чистый XML, чтобы SAX работал? Его опция --recover может быть полезна.

xmllint --recover test.xml

Он выведет ошибки на stderr и код на stdout, так что вы можете легко передать его в другой файл.

Что касается написания вашего собственного парсера ... почему? У вас есть другие доступные вам варианты, и изобретать красиво реализованное колесо - нецелесообразное использование времени.

...