drgnfly-creatns has asked for the wisdom of the Perl Monks concerning the following question:

I am new to cgi modules but more knowledgable than my associates. So I've been recently given the task of generating an xml file from the data provided by a html form. After doing some research I came across CGI:XML and XUpdate(Part of XML:DB). They both seem able to do what I need however I don't know much about either.

Here is what I want to be able to do:
1 - Have a html page with a form
2 - A cgi script that writes the data from the form to an xml file.

This is where the problem begins. How should the html form design coordinate with the cgi script to parse the data into an xml file. I can't find any tutorials on this concept but yet everywhere I read, it is do-able.

I don't have any starter code to display, I just really need someone to point me to a good tutorial on this or a small sample with both the html & perl script.

Any help would be more than I have now. Thanks

Replies are listed 'Best First'.
Re: HTML Form Data to XML file
by kvale (Monsignor) on Mar 03, 2004 at 02:33 UTC
    Once a user submits a form, the data is transported back to your server and handed off to a CGI program. To get the form data, I would recommend using CGI. Once you have the data in hand, you could write an XML file using a module like XML::Generator.

    For a tutorial on CGI, check out the CGI tutorials at Tutorials. For XML::Generator, check out the documentation that comes with the module, it is pretty simple.

    -Mark

Re: HTML Form Data to XML file
by mirod (Canon) on Mar 03, 2004 at 09:35 UTC

    You need 2 things: a form and a script that processes it. Actually you can also have the script create the form, which lets you have anything in one place.

    Below is a simple example. It uses CGI to process generate and process the form, and XML::Simple to turn the parameters into XML. You obviously need to have the script setup so it can run as a cgi on your server. Also the data should not be in the web tree, and beware of the security implications of letting an outside client create data on your machine.

    #!/usr/bin/perl -w use strict; use CGI qw/:standard :cgi-lib/; use XML::Simple; # the web server needs create and write access to that file # it should probably not be in the web tree (under DocumentRoot # or any accessible directory like cgi-bin and al. under Apache) my $OUT= "/web/data/out.xml"; # dispatch table <function param> => <sub that processes it> my %process= ( display_form => \&display_form, process_form => \&process_form, ); my $function= param( 'function') || 'display_form'; # display_form is +the default Delete( 'function'); # we don't need to save function in the XML, so l +et's remove it if( my $process= $process{$function}) { $process->(); } else { display( p( h2( "Error")), p( "wrong function '$function'") ); } exit; # the interesting part, gets the params and saves them as XML sub process_form { # from CGI get all the params my %params = Vars; # only useful if you have checkbox_group (that can take severa +l values # for a single param). There might be a better way, but this s +houd work foreach my $param (%params) { next unless( defined $params{$param}); # to avoid warni +ngs when the param is not filled my @values= split("\0", $params{$param}); # multiple v +alues are separated by a null char if( @values > 1) { $params{$param}= [ @values ] } } # from XML::Simple turn them into xml read the docs! my $xml= XMLout( \%params, noattr => 1, rootname => 'data', xmlde +cl => 1 ); # I am being extra-paranoid here, but you never know # notethat this sends an Internal Error to the client open( OUT, '>', $OUT) or die "cannot open $OUT: $!"; print( OUT $xml) or die "could not print in $OUT: $!"; close OUT or die "could not close $OUT: $!"; # send back an acknowledgement and the data (escaped, in pre tags) display( p( "OK, XML data saved in $OUT"), pre( escapeHTML( $xml)) +); } # this is just an example, the generated form can be in a separate fil +e, # or generated using a templating module (see Text::Template or HTML:: +Template) # the form here is straight out of the CGI docs sub display_form { display( h1('A Simple Example'), start_form, hidden( function => 'process_form'), "What's your name? ",textfield('name'),p, "What's the combination?", p, checkbox_group(-name=>'words', -values=>['eenie','meenie','minie','moe' +], -defaults=>['eenie','minie']), p, "What's your favorite color? ", popup_menu(-name=>'color', -values=>['red','green','blue','chartreuse'] +),p, submit, end_form, hr ) } # a helper sub that wraps the text to be displayed sub display { print header, # HTTP header start_html('A Simple Example'), # title @_, # what we want to display end_html; }
Re: HTML Form Data to XML file
by Anonymous Monk on Mar 03, 2004 at 16:54 UTC
    Take a look at XML::Smart, is the faster way to start working with XML and CGI. Here's an example of use:
    use XML::Smart ; sub process_form { my (%form , $buffer) ; if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}) ; } else { $buffer = $ENV{'QUERY_STRING'} } my @name_value_pairs = split('&',$buffer) ; foreach my $name_value_pair (@name_value_pairs) { my ($name,$value) = split('=',$name_value_pair); $value =~ tr/+/ /; $value =~ s/%([0-9A-Fa-f]{2})/pack("C",hex($1))/eg; $form{$name} = $value; } return %form ; } my %form = process_form() ; my $xml = XML::Smart->new() ; $xml->{form} = \%form ; print $xml->data ;

      Please, please, please! Why would you write your own CGI parser when CGI or CGI::Lite do it better and safer?

      Or did I just feed the troll? ;--(