Какую библиотеку Ruby XML вы бы порекомендовали для файла размером 2,4 МБ? - PullRequest
17 голосов
/ 24 сентября 2008

У меня есть 2,4 МБ XML-файл, экспорт из Microsoft Project (эй, я здесь жертва!), Из которого меня просят извлечь некоторые детали для повторного представления. Не обращая внимания на интеллектуальные или иные аспекты запроса, какую библиотеку мне следует сначала попробовать с точки зрения Ruby?

Мне известно следующее (в произвольном порядке):

Я бы предпочел что-то, упакованное как драгоценный камень Ruby, но я подозреваю, что библиотека Chilkat - нет.

Производительность не является серьезной проблемой - я не ожидаю, что она будет запускаться чаще, чем раз в день (более вероятно, раз в неделю). Меня больше интересует то, что так же легко использовать, как и все, что связано с XML.

РЕДАКТИРОВАТЬ: я пробовал драгоценные из них:

hpricot, на милю страны, самый легкий. Например, чтобы извлечь содержимое тега SaveVersion в этот XML-файл (сохраненный в файле с именем, скажем, «test.xml»)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/project">
    <SaveVersion>12</SaveVersion>
</Project>

принимает что-то вроде этого:

doc = Hpricot.XML(open('test.xml'))
version = (doc/:Project/:SaveVersion).first.inner_html

hpricot, по-видимому, относительно не связан с пространствами имен, что в этом примере хорошо: есть только один, но потенциально может быть проблемой со сложным документом. Поскольку hpricot также очень медленный, я скорее представляю, что эта проблема решается сама собой.

libxml-ruby на порядок быстрее, понимает пространства имен (мне понадобилось пару часов, чтобы понять это) и в целом намного ближе к металлу XML - запросы XPath и все остальное есть. Это не обязательно хорошо, если, как и я, вы открываете документ XML только в условиях крайней необходимости. Вспомогательный модуль был в основном полезен для предоставления примеров того, как эффективно обрабатывать пространство имен по умолчанию. Это примерно то, чем я закончил (я ни в коем случае не утверждаю его красоту, правильность или другую ценность, это просто то, где я сейчас нахожусь):

xml_parser = XML::Parser.new
xml_parser.string = File.read(path)
doc = xml_parser.parse
@root = doc.root
@scopes = { :in_node => '', :in_root => '/', :in_doc => '//' }
@ns_prefix = 'p'
@ns = "#{@ns_prefix}:#{@root.namespace[0].href}"
version = @root.find_first(xpath_qry("Project/SaveVersion", :in_root), @ns).content.to_i

def xpath_qry(tags, scope = :in_node)
  "#{@scopes[scope]}" + tags.split(/\//).collect{ |tag| "#{@ns_prefix}:#{tag}"}.join('/')
end

Я до сих пор спорю о плюсах и минусах: libxml за его дополнительную строгость, hpricot за чистый стиль кода _why.

РЕДАКТИРОВАТЬ снова, несколько позже: я обнаружил HappyMapper ('gem install happymapper'), который очень перспективен, хотя все еще находится на ранней стадии. Это декларативный и в основном работает, хотя я заметил несколько крайних случаев, для которых у меня еще нет исправлений. Это позволяет вам делать такие вещи, которые анализирует мой Google Reader OPML:

module OPML
  class Outline
    include HappyMapper
    tag 'outline'
    attribute :title, String
    attribute :text, String
    attribute :type, String
    attribute :xmlUrl, String
    attribute :htmlUrl, String
    has_many :outlines, Outline
  end
end

xml_string = File.read("google-reader-subscriptions.xml")

sections = OPML::Outline.parse(xml_string)

Я уже люблю это, хотя это еще не идеально.

Ответы [ 2 ]

4 голосов
/ 18 сентября 2009

Nokogiri оборачивает libxml2 и libxslt чистым Rubyish API, который поддерживает пространства имен, запросы XPath и CSS3. Быстро тоже. http://nokogiri.org/

3 голосов
/ 29 сентября 2008

Hpricot , вероятно, лучший инструмент для вас - он прост в использовании и должен обрабатывать 2 мг файла без проблем.

Speedwise libxml должен быть лучшим. Я использовал привязку libxml2 для python несколько месяцев назад (в тот момент rb-libxml был устаревшим). Потоковый интерфейс работал лучше всего для меня (LibXML :: XML :: Reader в рубиновом геме). Он позволяет обрабатывать файл во время загрузки, немного более удобен для пользователя, чем SAX, и позволил мне загружать данные из файла XML размером 30 МБ из Интернета в базу данных MySQL чуть более минуты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...