#!/usr/bin/perl -Tw use strict; $|++; use CGI qw(:all); ### globals ## mapping from SQL column name to XML state my @column_def = map [ m{^(\S+)\s+(.*)} ], <<'END_DEFINITION' =~ /(.+)/g; Name perl-mongers group name City perl-mongers group location city State perl-mongers group location state Country perl-mongers group location country Tsar_name perl-mongers group tsar name Tsar_email perl-mongers group tsar email Web perl-mongers group web END_DEFINITION ## reductions of data above my @columns = map $_->[0], @column_def; my %column_mapping = map { $_->[1] => $_->[0] } @column_def; ## end globals print header, start_html("Search the mongers info"), h1("Search the mongers info"), hr, start_form, table({ Border => 1, Cellspacing => 0, Cellpadding => 2 }, (map { Tr(th($_), td(textfield(-Name => $_, -Default => '%'))) } @columns), Tr(td({ Colspan => 2}, p("Use % for any chars, and ? for a single char"))), ), reset, submit, end_form, hr; &handle_form() if param(); print end_html; sub handle_form { require XML::Parser; require DBI; require LWP::Simple; my $dbh = DBI->connect('dbi:RAM:', undef, undef, {RaiseError => 1}); $dbh->do("CREATE TABLE table1 (". (join ", ", map "$_ TEXT", @columns). ")"); my $insert = $dbh->prepare("INSERT INTO table1 (". (join ", ", @columns). ") VALUES (". (join ",", ("?") x @columns).")"); my $data = LWP::Simple::get("http://www.pm.org/XML/perl_mongers.xml"); MyParser::doParse($data, $insert); my $extract = $dbh->prepare("SELECT ". (join ", ", @columns). " FROM table1". " WHERE ". (join " AND ", map "$_ LIKE ?", @columns). " ORDER BY Name"); $extract->execute(map {defined param($_) ? param($_) : "%"} @columns); print table({Border => 1, Cellspacing => 0, Cellpadding => 2}, Tr(th(\@columns)), map Tr(td($_)), @{$extract->fetchall_arrayref}); } BEGIN { package MyParser; my @state; my %one_group_data; my $insert_handle; sub doParse { my $data = shift; $insert_handle = shift; ## outer scope XML::Parser->new(Style => 'Stream')->parse($data); } sub StartTag { my ($parser, $type) = @_; push @state, $type; if ("@state" eq "perl-mongers group") { %one_group_data = (); } } sub EndTag { my ($parser, $type) = @_; if ("@state" eq "perl-mongers group") { $insert_handle->execute(@one_group_data{@columns}); } pop @state; } sub Text { my $place = $column_mapping{"@state"}; if (defined $place) { $one_group_data{$place} .= $_; } } }