He estado unos dÃas en un proyecto donde querÃa echar un cable, se trataba de una migración de un fichero generado al exportar una base de datos de Geslib, un software utilizado para la gestión integral de las librerÃas, a una plataforma web hecha en Drupal y que usará el Feeds para llevar a cabo la importación.
Asà que partimos de un fichero formado por una serie de lÃneas tipificadas de una manera determinada y se utiliza como delimitador de campo ‘|’ (ALT + 124 , “pipeâ€). La idea inicial era crear un fichero CSV que se pudiera importar, pero en ocasiones leer un fichero CSV con muchas entradas puede ser un infierno asà que mejor crear un XML :-).
Como en el fichero exportado viene todo junto, materias, idiomas, autores, libros, categorÃas, etc, pues primero tirando de bash cortamos el fichero inicial en diferentes ficheros separados por tipos de cosas, es decir, generamos un fichero para autores, otro para idiomas, etc… aquà sólo me centraré en el de libros, que es para el que se ha hecho el XML.
Haciendo uso del bash cortamos el fichero original, identificamos cuales son los libros (las lÃneas que empiezan por GPA) y creamos un fichero llamado libros_VERSION.csv
grep "^GP4|A" NOMBRE-UTF8 >> libros_NOMBRE-VERSION.csv
sed -i 's/^GP4|A|//g' libros_NOMBRE-VERSION.csv
Esto nos devuelve un fichero con este formato, cosa que para la lectura es un poco incómodo, aunque le pongas headers y aunque se lea en una hoja de cálculo
9465|ETERNO RETORNO|EINSTEIN|1331||9789200094651||||||||||239|20061129|20061129|1||||1|||0|0,00|8,00|A0|1|1|6,90|||||||||16,00|||0,00||
10148|BASADO EN UNA HISTORIA REAL|HABEAS CORPUS|1664||8429085290076||||||||||239|20061213||1||||1|||0|0,00|10,00|A0|1|2|8,62|||||||||16,00|||0,00||
10362|MIDAS S.A.|EQUIPO DE COMUNICACION EDUCATIVA|1997||9789200103629|||||||||1|239|20061219||1||||1|||0|0,00|12,00|A0|1|3|10,17||106|||||||18,00|||0,00||
11097|CONTAMÃNAME|VV.AA.|1331||8287675903252||||||||||239|20070209||1||||1|||0|0,00|8,00|A0|1|4|6,90|||||||||16,00|||0,00||
 por eso querÃamos crear un XML, que sea más legible y en ruby realmente de una manera fácil se puede hacer el siguiente script usando la clase CSV de ruby y la gema XML builder, si no lo has usado hasta ahora sólo hay que
$gem install builder
Y el script quedarÃa de la siguiente manera
#!/usr/bin/ruby
require 'builder'
require 'csv'
xml = Builder::XmlMarkup.new( :target => $stdout, :indent => 2 )
xml.instruct! : xml, :version => "1.1", :encoding => "UTF-8"
#2 dimensions array , separador el ;
geslib = CSV.read("libros_XXX.csv", :col_sep => ";")
xml.geslib do
geslib.each do |book|
xml.book do
xml.book_code book[0]
xml.title book[1]
xml.author book[2]
xml.pvp_ptas book[3]
xml.isbn book[4]
xml.ean book[5]
end
end
end
Al ejecutar el script nos daba el siguiente error
/home/usuario/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/csv.rb:1922:in `block (2 levels) in shift’: Unquoted fields do not allow \r or \n (line 2). (CSV::MalformedCSVError)
y eso es porque el fichero exportado del Geslib tiene como salto de lÃnea el creado por Windows(\r\n), con lo cual en GNU/Linux no le gusta(pues usa \r), asà que para limpiar los finales de lÃnea usamos el comando tr la terminal que nos permite borrar caracteres, asà que borramos \n de la siguiente manera
tr -d “\n” < libros_XXXXX.csv > libros_XXXXX_limpio.csv
Volvemos a ejecutar
$ruby parser_xml_geslib.rb
y obtenemos nuestro XML (sólo es la muestra de 1 libro formateado en XML, que sino es muy largo 😉 )
<?xml version=”1.1″ encoding=”UTF-8″?>
<geslib>
<book>
<book_code>15797</book_code>
<title>SKA ZONE</title>
<author>DISCIPULOS DE OTILIA</author>
<pvp_ptas>832</pvp_ptas>
<isbn/>
<ean>8430106010627</ean>
</book>
</geslib>
Muy interesante. Gracias!, voy a intentarlo, aunque me pierdo un poco
hola que hace falta para utilizar ruby y poder hacer este script?