使用Perl从XML配置文件生成HTML Web表单,反之亦然

时间:2012-08-25 02:02:36

标签: html xml perl perl-module

我需要以下问题的帮助。有一个我共同编写并且当前管理的应用程序,它是用C和Haskell组合编写的。可以通过单个XML文件自定义和配置应用程序。它是一个没有用户界面的后端应用程序。我们被要求通过Web界面为该应用程序提供图形界面。每个配置选项都是html表单中的表单字段,如此

configuration1  string1
configuration2  string2
etc
etc

图形前端必须是一个Web表单,用于将用户输入的数据转换为包含应用程序设置的XML文件。当用户保存表单时,更改将写入XML文件。当用户打开表单时,XML文件中的配置将显示在HTML表单字段中。

我们的团队处理纯粹的后端内容,我们对GUI等都一无所知。我们的限制是前端必须用Perl编写,并使用LibXML模块符合公司标准。我们的团队纯粹是C和Haskell,这是我们收到的第一个类似的请求。我很感激您提供的任何帮助。如果您可以尽可能详细地包含代码示例,那将是一个重要的帮助。我们对Perl知之甚少但有足够明确的例子我们可以做到。通常会处理此类内容的团队正在重组,我们不能等待,因为我们需要尽快启动此接口。

谢谢。

2 个答案:

答案 0 :(得分:0)

不要自己这样做。您不知道Perl或Web应用程序,您提到的有关libxml的限制可能只是其中之一。每个微小的配置和打字错误都需要花费数小时或数天时间才能弄明白。你最终会感到悲惨和压力,用户也会如此。

您的网络团队中的某个人可以在一天内制作一个包含测试和文档的简单表单。然后,您可以在从工作应用程序开始的知识中扩展并修复安全漏洞。

如果你不能在内部找人,你就会雇佣一名程序员,但要尽一切努力在内部完成。不要自己这样做。

答案 1 :(得分:0)

对于OP:您没有正确描述配置格式,XML片段可以帮助我们。因为它可能需要修改下面的解决方案以匹配您的格式。

我假设了以下格式:

<conf>
  <option><name>configuration1</name><value>string1 modified</value></option>
  <option><name>configuration2</name><value>string2 re-modded</value></option>
  <option><name>configuration3</name><value>string3</value></option>
</conf>

处理这种格式的代码是:

#!/usr/bin/perl 

use strict;
use warnings;

use CGI qw( -nosticky -utf8 :standard form );
use XML::LibXML;

my $CONF="/web/data/conf.xml"; # or wherever your XML is located

# dispatch table, action => code to process it
my $dispatch= { display => \&display_conf,
                edit    => \&display_edit_form,
                save    => \&save_edits,
              };

# action is "what to do"
my $action= param( 'action') || 'display';

$dispatch->{$action}->() || exit_error( "wrong action");
exit;

# load the XML and build a table to display it
sub display_conf
  { my $conf= XML::LibXML->load_xml( location => $CONF);
    my $content;
    foreach my $option ($conf->findnodes( '/conf/option'))
      { $content .= Tr( td( $option->findvalue( './name')), 
                        td( $option->findvalue( './value'))
                      );
      }
    $content= table( $content);
    # add a link to the edit form
    $content .= p( a({ href => url() . '?action=edit' }, 'edit')); 
    output( $content);                
  }

# load the XML and build a form that will let you edit it
sub display_edit_form
  { my $conf= XML::LibXML->load_xml( location => $CONF);
    my $content;
    foreach my $option ($conf->findnodes( '/conf/option'))
      { $content .= Tr( td( $option->findvalue( './name')), 
                        td( input( { type => "text", size => 40, 
                                     name => $option->findvalue( 'name'), 
                                     value => $option->findvalue( './value')}
                                 )
                          )
                      );
      }
    $content= table( $content);
    $content= form( { action => url() }, 
                    hidden( { name => 'action', value => 'save', override => 1 }),
                    $content,
                    submit( 'Save'),
                  );
    output( $content);                
  }

# load the XML, go through all options, update the value from the form, 
# save the XML, display it value, from the form
sub save_edits
  { my $conf= XML::LibXML->load_xml( location => $CONF);
    foreach my $option ($conf->findnodes( '/conf/option'))
      { my $new_value= param( $option->findvalue( './name'));
        my( $value_node)= $option->findnodes( './value');
        $value_node->removeChildNodes();
        $value_node->appendText( $new_value);
      }
    $conf->toFile( $CONF);
    display_conf();
  }

# placeholder, 
sub exit_error
  { my $message= shift;
    print header(), p($message);
  }

# output subs, load the template, inject the content and output (with header)   

sub output
  { my $content= shift;
    print header(), fill_in_string( template(), content => $content );
  }


sub fill_in_string
  { my( $template, %param)= @_;
    $template=~ s{<<(\w+)>>}{$param{$1}}g;
    return $template;
  }

sub template
  { return join '', <DATA>; }

# template, very simple
__DATA__
<html>
  <head>
    <title>Configuration Editor</title>
  </head>
  <body>
    <h1>Configuration Editor</h1>
    <h2>Configuration</h2>
      <<content>>
    </h2>
  </body>
</html>

部署:将代码放在可以作为CGI运行的地方,并确保Web服务器可以读取和写入conf.xml。将它放在网络树之外可能更好。

这是史前Perl的一种方式。 CGI被广泛认为是古老的,Perl中有更多现代和花哨的选择。如果您的配置比键/值列表更复杂,如果您希望为每个字段提供自定义帮助,或者如果您需要使用更复杂的模板以符合您公司的外观,那么Web框架就像Dancer或Mojolicious比上面的简单解决方案更适合。

OTOH它的工作原理,我仍然是如何编写许多小工具,它们有一些内部用户,并且在UI方面不需要太多。

对于那些认为这对于不熟悉Perl的人来说太复杂的人来说,这样做的方法是什么!这不是航天科技。这是让人们从Perl开始的代码,为什么我们不帮助编写它?这实际上是The Reluctant Perl Programmer的完美例证。