Tengo un archivo XML de 2.4 MB, una exportación de Microsoft Project (¡ojalá yo sea la víctima aquí!) De la cual se me solicita extraer ciertos detalles para la presentación. Ignorando la inteligencia o no de la solicitud, ¿qué biblioteca debo probar primero desde la perspectiva de Ruby?¿Qué biblioteca de Ruby XML recomendaría para un archivo XML de 2.4MB?
Soy consciente de los siguientes (en ningún orden particular):
yo preferiría algo empaquetado como una gema Ruby, que sospecho que la biblioteca Chilkat no es.
El rendimiento no es un problema importante. No creo que deba ejecutarse más de una vez al día (una vez por semana es más probable). Estoy más interesado en algo que es tan fácil de usar como cualquier cosa relacionada con XML.
EDIT: He probado el gemified los:
hpricot es, por una milla del país, más fácil. Por ejemplo, para extraer el contenido de la etiqueta SaveVersion en este XML (guardado en un archivo llamado, decir 'test.xml')
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/project">
<SaveVersion>12</SaveVersion>
</Project>
toma algo como esto:
doc = Hpricot.XML(open('test.xml'))
version = (doc/:Project/:SaveVersion).first.inner_html
hpricot parece no se preocupe por los espacios de nombres, que en este ejemplo está bien: solo hay uno, pero podría ser un problema con un documento complejo. Como hpricot también es muy lento, prefiero imaginarme que este sería un problema que se resuelve solo.
libxml-ruby es un orden de magnitud más rápido, entiende los espacios de nombres (me tomó un par de horas resolver esto) y está mucho más cerca del XML metal - las consultas XPath y todas las demás cosas están ahí . Esto no es necesariamente algo bueno si, como yo, abres un documento XML solo bajo condiciones de extrema coacción. El módulo de ayuda fue en gran medida útil para proporcionar ejemplos de cómo manejar un espacio de nombres predeterminado con eficacia. Esto es más o menos lo que terminó con (no estoy de ninguna manera la afirmación de su belleza, corrección u otro valor, que es justo donde estoy ahora):
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
Todavía estoy debatiendo los pros y los contras : libxml por su rigor extra, hpricot por el estilo puro del código de _why.
EDIT otra vez, un poco después: descubrí HappyMapper ('gem install happymapper') que es muy prometedor, si todavía está en una etapa temprana. Es declarativo y funciona en su mayoría, aunque he descubierto un par de casos extremos para los que aún no tengo soluciones. Te permite hacer cosas como esta, que analiza mi 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)
ya Me encanta, a pesar de que todavía no es perfecto.
¡Oh, no! ¡Un archivo XML de 2.4 mb! ¡EL HORROR! – Will
Bueno, pensé que la respuesta podría ser diferente si fuera de 2,4 GB ...;) –