Using perl Syntax Highlighting
#!/usr/bin/perl
use HTML::TableExtract;
use XML::Simple;
use warnings;
use strict;
# Subrutinas
sub filtra ($) {
$_ = shift;
s/^\s*//;
s/\s*$//;
return $_;
}
sub campea ($) {
$_ = shift;
y/ \n/_/s;
y/ÁÉÍÓÚáéíóúñüç/aeiouaeiounuc/;
y/()//d;
return lc $_;
}
# Leemos el HTML
my $html = do { undef $/; open HTML,"<datos.html"; <HTML> };
# Variables
my %xml;
my $te;
my $tabla;
# Análisis
$te = HTML::TableExtract->new( );
$te->parse($html);
# Datos PPI
$tabla = $te->table(2,2);
$xml{ ppi }{ numero } = filtra $tabla->cell(0,0);
$xml{ ppi }{ condicion } = filtra $tabla->cell(0,1);
# Datos personales
$tabla = $te->table(3,2);
$xml{ personal }{ nombre } = filtra $tabla->cell(0,0);
$xml{ personal }{ nacionalidad } = filtra $tabla->cell(0,1);
$xml{ personal }{ sexo } = filtra $tabla->cell(0,2);
# Resto de datos
# Se encuentran en tablas de profundidad 1
$te = HTML::TableExtract->new( depth => 1 );
$te->parse($html);
# Índices que llevarán la cuenta de los elementos leídos de cada clase
my $i_instituto = 0;
my $i_estudios = 0;
my $i_conferencia = 0;
my $i_publica = 0;
# Leeremos las tablas y según el primer valor leído lo guardaremos
# en una u otra estructura del xml
foreach $tabla ( $te->tables ) {
my @filas = $tabla->rows;
# Si el número de filas es 0, salimos del bucle
next if @filas == 0;
# Leemos primer valor de la fila (nombre del campo)
my $primera_celda = $filas[0][0];
next unless defined $primera_celda;
# Según ese valor
if ( $primera_celda eq 'Institución' ) {
foreach my $fila ( @filas ) {
$xml{ institucionales }{ institucion }[ $i_instituto ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_instituto++;
}
elsif ( $primera_celda eq 'Grado' ) {
foreach my $fila ( @filas ) {
$xml{ estudios }{ estudio }[ $i_estudios ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_estudios++;
}
elsif ( $primera_celda eq 'Nombre Evento' ) {
foreach my $fila ( @filas ) {
$xml{ conferencias }{ conferencia }[ $i_conferencia ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_conferencia++;
}
elsif ( $primera_celda eq 'Año' ) {
foreach my $fila ( @filas ) {
$xml{ publicaciones }{ publicacion }[ $i_publica ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_publica++;
}
}
# Finalmente, campos de actuación
# Se encuentran en una tabla de profundidad 2, cuya primera celda vale 'Área'
$te = HTML::TableExtract->new( depth => 2 );
$te->parse($html);
my $i_actuacion = 0;
foreach $tabla ( $te->tables ) {
my @filas = $tabla->rows;
# Si el número de filas es 0, salimos del bucle
next if @filas == 0;
# Leemos primer valor de la fila (nombre del campo)
my $primera_celda = $filas[0][0];
next unless defined $primera_celda and $primera_celda eq 'Área';
# Guardamos sus valores
foreach my $fila ( @filas ) {
$xml{ actuaciones }{ actuacion }[ $i_actuacion ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_actuacion++;
}
# Salida
print XMLout( \%xml, RootName=>'alumno', noattr => 1, xmldecl => '<?xml version="1.0" ?>');
use HTML::TableExtract;
use XML::Simple;
use warnings;
use strict;
# Subrutinas
sub filtra ($) {
$_ = shift;
s/^\s*//;
s/\s*$//;
return $_;
}
sub campea ($) {
$_ = shift;
y/ \n/_/s;
y/ÁÉÍÓÚáéíóúñüç/aeiouaeiounuc/;
y/()//d;
return lc $_;
}
# Leemos el HTML
my $html = do { undef $/; open HTML,"<datos.html"; <HTML> };
# Variables
my %xml;
my $te;
my $tabla;
# Análisis
$te = HTML::TableExtract->new( );
$te->parse($html);
# Datos PPI
$tabla = $te->table(2,2);
$xml{ ppi }{ numero } = filtra $tabla->cell(0,0);
$xml{ ppi }{ condicion } = filtra $tabla->cell(0,1);
# Datos personales
$tabla = $te->table(3,2);
$xml{ personal }{ nombre } = filtra $tabla->cell(0,0);
$xml{ personal }{ nacionalidad } = filtra $tabla->cell(0,1);
$xml{ personal }{ sexo } = filtra $tabla->cell(0,2);
# Resto de datos
# Se encuentran en tablas de profundidad 1
$te = HTML::TableExtract->new( depth => 1 );
$te->parse($html);
# Índices que llevarán la cuenta de los elementos leídos de cada clase
my $i_instituto = 0;
my $i_estudios = 0;
my $i_conferencia = 0;
my $i_publica = 0;
# Leeremos las tablas y según el primer valor leído lo guardaremos
# en una u otra estructura del xml
foreach $tabla ( $te->tables ) {
my @filas = $tabla->rows;
# Si el número de filas es 0, salimos del bucle
next if @filas == 0;
# Leemos primer valor de la fila (nombre del campo)
my $primera_celda = $filas[0][0];
next unless defined $primera_celda;
# Según ese valor
if ( $primera_celda eq 'Institución' ) {
foreach my $fila ( @filas ) {
$xml{ institucionales }{ institucion }[ $i_instituto ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_instituto++;
}
elsif ( $primera_celda eq 'Grado' ) {
foreach my $fila ( @filas ) {
$xml{ estudios }{ estudio }[ $i_estudios ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_estudios++;
}
elsif ( $primera_celda eq 'Nombre Evento' ) {
foreach my $fila ( @filas ) {
$xml{ conferencias }{ conferencia }[ $i_conferencia ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_conferencia++;
}
elsif ( $primera_celda eq 'Año' ) {
foreach my $fila ( @filas ) {
$xml{ publicaciones }{ publicacion }[ $i_publica ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_publica++;
}
}
# Finalmente, campos de actuación
# Se encuentran en una tabla de profundidad 2, cuya primera celda vale 'Área'
$te = HTML::TableExtract->new( depth => 2 );
$te->parse($html);
my $i_actuacion = 0;
foreach $tabla ( $te->tables ) {
my @filas = $tabla->rows;
# Si el número de filas es 0, salimos del bucle
next if @filas == 0;
# Leemos primer valor de la fila (nombre del campo)
my $primera_celda = $filas[0][0];
next unless defined $primera_celda and $primera_celda eq 'Área';
# Guardamos sus valores
foreach my $fila ( @filas ) {
$xml{ actuaciones }{ actuacion }[ $i_actuacion ]{ campea filtra $fila->[0] } = filtra $fila->[1];
}
$i_actuacion++;
}
# Salida
print XMLout( \%xml, RootName=>'alumno', noattr => 1, xmldecl => '<?xml version="1.0" ?>');
Coloreado en 0.007 segundos, usando GeSHi 1.0.8.4
Salida (sólo un extracto de ella):
Using xml Syntax Highlighting
<?xml version="1.0" ?>
<alumno>
<actuaciones>
<actuacion>
<area>ECONOMICAS</area>
<disciplina>*Teoría económica</disciplina>
<especialidad>- Teoría microeconómica</especialidad>
<linea_de_investigacion>Estudio de Competitividad Industrial y Tendencias de la Universidad Contemporanea</linea_de_investiga
</actuacion>
</actuaciones>
<conferencias>
<conferencia>
<ano>2005</ano>
<autores>Juliana Ferrer</autores>
<nombre_evento>Conferencia Taller Formación de Equipos y escuelas de investigación de alta calidad académica. Reto de las Uni
<titulo_trabajo>Formación de Equipos y escuelas de investigación de alta calidad académica. Reto de las Universidades Pública
</conferencia>
<conferencia>
<ano>2005</ano>
<autores>Juliana Ferrer</autores>
<nombre_evento>III Congreso Iberoamericano de Administración Empresarial y Contabilidad. I Encuentro Internacional de Adminis
<titulo_trabajo>La Ética gerencial como factor competitivo en las pequeñas y medianas empresas venezolanas</titulo_trabajo>
</conferencia>
# ...
</conferencias>
<estudios>
<estudio>
<ano>2001</ano>
<grado>Doctorado</grado>
<institucion>Universidad Dr. Rafael Belloso Chacín - URBE</institucion>
<mencion>Ciencias Gerenciales</mencion>
</estudio>
<estudio>
<ano>1990</ano>
<grado>Maestria</grado>
<institucion>Universidad del Zulia</institucion>
<mencion>Gerencia de Mercadeo</mencion>
</estudio>
# ---
</estudios>
<institucionales>
<institucion>
<ciudad>Maracaibo</ciudad>
<codigo_postal>4001</codigo_postal>
<correo_electronico>[email protected]; [email protected]</correo_electronico>
<direccion>Facultad de Cs. Económicas y Sociales, Ciudad Universitaria. LUZ. Maracaibo</direccion>
<direccion_web></direccion_web>
<estado>Zulia</estado>
<institucion>LUZ - Universidad del Zulia</institucion>
<pais>Venezuela</pais>
</institucion>
</institucionales>
<personal>
<nacionalidad>Venezolana</nacionalidad>
<nombre>Ferrer Soto, Juliana</nombre>
<sexo>F</sexo>
</personal>
<ppi>
<condicion>Activo</condicion>
<numero>4291</numero>
</ppi>
<publicaciones>
<publicacion>
<ano>2005</ano>
<area>ECONOMICAS</area>
<autor>Caterina Clemenza, Juliana Ferrer y Nancy Andrade</autor>
<disciplina>*Economía sectorial</disciplina>
<lugar>Maracaibo, Venezuela, LUZ</lugar>
<paginas>1-38</paginas>
<revista>Revista Venezolana de Trabajo Social</revista>
<tipo>Artículo en Revista nacional registrada en índice internacional reconocido por el PPI</tipo>
<titulo>Universidad y Sector Productivo. Una Cohesión Impostergable</titulo>
<volumen>II, 2.</volumen>
</publicacion>
# ...
</publicaciones>
</alumno>
<alumno>
<actuaciones>
<actuacion>
<area>ECONOMICAS</area>
<disciplina>*Teoría económica</disciplina>
<especialidad>- Teoría microeconómica</especialidad>
<linea_de_investigacion>Estudio de Competitividad Industrial y Tendencias de la Universidad Contemporanea</linea_de_investiga
</actuacion>
</actuaciones>
<conferencias>
<conferencia>
<ano>2005</ano>
<autores>Juliana Ferrer</autores>
<nombre_evento>Conferencia Taller Formación de Equipos y escuelas de investigación de alta calidad académica. Reto de las Uni
<titulo_trabajo>Formación de Equipos y escuelas de investigación de alta calidad académica. Reto de las Universidades Pública
</conferencia>
<conferencia>
<ano>2005</ano>
<autores>Juliana Ferrer</autores>
<nombre_evento>III Congreso Iberoamericano de Administración Empresarial y Contabilidad. I Encuentro Internacional de Adminis
<titulo_trabajo>La Ética gerencial como factor competitivo en las pequeñas y medianas empresas venezolanas</titulo_trabajo>
</conferencia>
# ...
</conferencias>
<estudios>
<estudio>
<ano>2001</ano>
<grado>Doctorado</grado>
<institucion>Universidad Dr. Rafael Belloso Chacín - URBE</institucion>
<mencion>Ciencias Gerenciales</mencion>
</estudio>
<estudio>
<ano>1990</ano>
<grado>Maestria</grado>
<institucion>Universidad del Zulia</institucion>
<mencion>Gerencia de Mercadeo</mencion>
</estudio>
# ---
</estudios>
<institucionales>
<institucion>
<ciudad>Maracaibo</ciudad>
<codigo_postal>4001</codigo_postal>
<correo_electronico>[email protected]; [email protected]</correo_electronico>
<direccion>Facultad de Cs. Económicas y Sociales, Ciudad Universitaria. LUZ. Maracaibo</direccion>
<direccion_web></direccion_web>
<estado>Zulia</estado>
<institucion>LUZ - Universidad del Zulia</institucion>
<pais>Venezuela</pais>
</institucion>
</institucionales>
<personal>
<nacionalidad>Venezolana</nacionalidad>
<nombre>Ferrer Soto, Juliana</nombre>
<sexo>F</sexo>
</personal>
<ppi>
<condicion>Activo</condicion>
<numero>4291</numero>
</ppi>
<publicaciones>
<publicacion>
<ano>2005</ano>
<area>ECONOMICAS</area>
<autor>Caterina Clemenza, Juliana Ferrer y Nancy Andrade</autor>
<disciplina>*Economía sectorial</disciplina>
<lugar>Maracaibo, Venezuela, LUZ</lugar>
<paginas>1-38</paginas>
<revista>Revista Venezolana de Trabajo Social</revista>
<tipo>Artículo en Revista nacional registrada en índice internacional reconocido por el PPI</tipo>
<titulo>Universidad y Sector Productivo. Una Cohesión Impostergable</titulo>
<volumen>II, 2.</volumen>
</publicacion>
# ...
</publicaciones>
</alumno>
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
El proceso seguido es:
* Con la ayuda de HTML::TableExtract, sacamos las tablas de un determinado nivel. Y según el valor de la primera celda, sabemos a qué categoría de información pertenece.
* Tenemos dos subrutinas. Una es para filtrar los campos (quitarles los espacios en blanco). Y la otra, 'campea', convierte los nombres de los campos a algo más parecido a una base de datos (sin espacios en blanco, ni acentos, en minúsculas, ni caracteres extraños).
* Se supone que los datos de PPI y datos personales son únicos (sólo aparecen una vez por página), mientras que el resto de las categorías sí que puede aparecer más de una vez.
* Se utiliza la técnica del prototipado de subrutinas, para no tener que usar los paréntesis en sus llamadas (es sólo una cuestión de estilo).
Actualización: Corregida la etiqueta <?xml ?>