如何在 Perl 中从 CSV 文件创建 HTML 下拉菜单?

发布于 2024-08-07 11:02:40 字数 750 浏览 1 评论 0原文

我正在创建一个网页来从 CSV 文件中选择一些选项:

CSV 文件示例:

Time,h1,h2,h3,....
00:00:00,n1,n2,n3.....
.....so on


h -> header
n -> numbers

下面是我编写的用于过滤标题和值并返回的 Perl 代码子例程:

sub TimeData
{
    use Text::CSV;
    my @time;
    my @data;
    my ($csv_file, $type) = @_;
    open(my $csv_fh, '<', $csv_file) or die $!;
    my $parser = Text::CSV->new();
    $parser->column_names( $parser->getline($csv_fh) );
    while ( defined( my $hr = $parser->getline_hr($csv_fh) ) )
    {
        push @time, $hr->{Time};
        push @data, $hr->{$type};   
    }

    return (@time, @data);
}

我想创建一个页面,其中输入字段具有包含 h1、h2、h3 等列表的下拉菜单。所选标头值可以用作另一个 Perl 脚本中的输入。任何人都可以建议一些代码来完成此任务。

I'm creating a web page to select some options from a CSV file:

CSV File Sample:

Time,h1,h2,h3,....
00:00:00,n1,n2,n3.....
.....so on


h -> header
n -> numbers

Below is the Perl code subroutine I have written to filter the header and values and return:

sub TimeData
{
    use Text::CSV;
    my @time;
    my @data;
    my ($csv_file, $type) = @_;
    open(my $csv_fh, '<', $csv_file) or die $!;
    my $parser = Text::CSV->new();
    $parser->column_names( $parser->getline($csv_fh) );
    while ( defined( my $hr = $parser->getline_hr($csv_fh) ) )
    {
        push @time, $hr->{Time};
        push @data, $hr->{$type};   
    }

    return (@time, @data);
}

I want to create a page where the input field has a drop down menu with the lists of h1, h2, h3, etc. The selected header value can be used as a input in another Perl script. Can anyone please suggest some code to get this done.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三生路 2024-08-14 11:02:40

请注意,您的 return 语句是有问题的:两个数组将被展平为一个,并且调用代码将无法将返回值分配给两个单独的数组。如果您想保留该界面的精神,您应该返回对这些数组的引用。请参阅 perldoc perlsub

return 语句可用于退出子例程,可以选择指定返回值,该值将根据子例程的上下文在适当的上下文(列表、标量或 void)中进行计算称呼。 ...如果您返回一个或多个聚合(数组和散列),它们将被展平到一个大的难以区分的列表中。

使用 split 因为我输入此内容的计算机既没有 Text::CSV 也没有 Text::xSV]。

#!/usr/bin/perl

use strict; use warnings;

my (@header) = map { chomp; split /,/} scalar <DATA>;

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    chomp $line;
    my (@values) = split /,/, $line;
    print "<select>\n";
    for (my $i = 1; $i < @header; $i += 1) {
        printf qq{<option name="%s" value="%s">%s = %s</option>\n},
               $header[$i], $values[$i], $header[$i], $values[$i];
    }
    print "</select>\n";
}

__DATA__
Time,h1,h2,h3
00:00:00,n1,n2,n3

现在,如果我正在做这样的事情,我会将读取数据的部分和生成 的部分分开,并为后者使用基于模板的方法。这是一个示例:

#!/usr/bin/perl

use strict; use warnings;

use HTML::Template;
use List::AllUtils qw( each_arrayref );

my $select_html = <<EO_HTML;
<select>
<TMPL_LOOP OPTIONS>
<option name="<TMPL_VAR HEADER>"
value="<TMPL_VAR VALUE>"><TMPL_VAR HEADER> = <TMPL_VAR VALUE></option>
</TMPL_LOOP>
</select>
EO_HTML

my @headers = qw(h1 h2 h3);
# Stand-in for rows you read from the CSV file
my @values  = ( [qw(a1 a2 a3)], [qw(b1 b2 b3)] );

print make_select(\$select_html, \@headers, $_)->output for @values;

sub make_select {
    my ($html, $headers, $values) = @_;
    my $tmpl = HTML::Template->new(scalarref => $html);

    my @options;

    my $it = each_arrayref($headers, $values);
    while ( my ($h, $v) = $it->() ) {
        push @options, { HEADER => $h, VALUE => $v };
    }
    $tmpl->param(OPTIONS => \@options);
    return $tmpl;
}

输出:

<select>

<option name="h1"
value="a1">h1 = a1</option>

<option name="h2"
value="a2">h2 = a2</option>

<option name="h3"
value="a3">h3 = a3</option>

</select>
<select>

<option name="h1"
value="b1">h1 = b1</option>

<option name="h2"
value="b2">h2 = b2</option>

<option name="h3"
value="b3">h3 = b3</option>

</select>

Note that your return statement is problematic: The two arrays will be flattened into one and the calling code will not be able to assign the return values to two separate arrays. If you want to keep the spirit of that interface, you should return references to those arrays. See perldoc perlsub:

A return statement may be used to exit a subroutine, optionally specifying the returned value, which will be evaluated in the appropriate context (list, scalar, or void) depending on the context of the subroutine call. ... If you return one or more aggregates (arrays and hashes), these will be flattened together into one large indistinguishable list.

Using split because the computer I am typing this on has neither Text::CSV nor Text::xSV].

#!/usr/bin/perl

use strict; use warnings;

my (@header) = map { chomp; split /,/} scalar <DATA>;

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    chomp $line;
    my (@values) = split /,/, $line;
    print "<select>\n";
    for (my $i = 1; $i < @header; $i += 1) {
        printf qq{<option name="%s" value="%s">%s = %s</option>\n},
               $header[$i], $values[$i], $header[$i], $values[$i];
    }
    print "</select>\n";
}

__DATA__
Time,h1,h2,h3
00:00:00,n1,n2,n3

Now, if I were doing something like this, I would separate the part where I read the data and where I generate the <SELECT></SELECT> and use a template based approach for the latter. Here is an example:

#!/usr/bin/perl

use strict; use warnings;

use HTML::Template;
use List::AllUtils qw( each_arrayref );

my $select_html = <<EO_HTML;
<select>
<TMPL_LOOP OPTIONS>
<option name="<TMPL_VAR HEADER>"
value="<TMPL_VAR VALUE>"><TMPL_VAR HEADER> = <TMPL_VAR VALUE></option>
</TMPL_LOOP>
</select>
EO_HTML

my @headers = qw(h1 h2 h3);
# Stand-in for rows you read from the CSV file
my @values  = ( [qw(a1 a2 a3)], [qw(b1 b2 b3)] );

print make_select(\$select_html, \@headers, $_)->output for @values;

sub make_select {
    my ($html, $headers, $values) = @_;
    my $tmpl = HTML::Template->new(scalarref => $html);

    my @options;

    my $it = each_arrayref($headers, $values);
    while ( my ($h, $v) = $it->() ) {
        push @options, { HEADER => $h, VALUE => $v };
    }
    $tmpl->param(OPTIONS => \@options);
    return $tmpl;
}

Output:

<select>

<option name="h1"
value="a1">h1 = a1</option>

<option name="h2"
value="a2">h2 = a2</option>

<option name="h3"
value="a3">h3 = a3</option>

</select>
<select>

<option name="h1"
value="b1">h1 = b1</option>

<option name="h2"
value="b2">h2 = b2</option>

<option name="h3"
value="b3">h3 = b3</option>

</select>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文