Usando ruby para crear XML

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>
 

 

2 thoughts on “Usando ruby para crear XML

Leave a Comment

Your email address will not be published. Required fields are marked *