如何在Template Toolkit中根据YAML条件输出到不同文件
问题
使用Perl结合Template Toolkit开发,读取test.yaml文件,根据YAML中的配置值,借助Template Toolkit将内容按目标文件分组输出。现有相关文件及预期输出如下,需要完成实现:
YAML文件(test.yaml)
--- constraints: data1: file: file1 value: 'Writing in file 1: DATA1' data2: file: file2 value: 'Writing in file 2: DATA2' data3: file: file1 value: 'Writing in file 1: DATA3'
Perl脚本(当前版本)
use strict; use warnings; use Template; use YAML qw(LoadFile); use Data::Dumper; my $tt = Template->new({ INCLUDE_PATH => './', INTERPOLATE => 1, }) or die "$Template::ERROR\n"; my %data = % {LoadFile('test.yaml') }; my $report; $tt->process('test.tt', \%data, \$report) or die $tt->error(), "\n"; print $report;
未完成的模板(test.tt)
[% FOREACH a IN constraints.keys.sort %] [% IF constraints.$a.file == 'file1' %] constraints.$a.value > file1 --------**Need help on this** [% ELSE %] constraints.$a.value > file2 --------**Need help on this** [% END %] [% END %]
预期输出
file1: Writing in file 1: DATA1 Writing in file 1: DATA3 file2: Writing in file 2: DATA2
解决方案
1. 调整Perl脚本:按目标文件分组数据
先在Perl中完成数据分组,把同一目标文件的内容归为一组,再传递给模板处理,能大幅简化模板逻辑。修改后的脚本如下:
use strict; use warnings; use Template; use YAML qw(LoadFile); my $tt = Template->new({ INCLUDE_PATH => './', INTERPOLATE => 1, }) or die "$Template::ERROR\n"; # 读取YAML数据 my $yaml_data = LoadFile('test.yaml'); # 按目标文件分组内容 my %grouped_data; foreach my $key (keys %{$yaml_data->{constraints}}) { my $item = $yaml_data->{constraints}->{$key}; push @{$grouped_data{$item->{file}}}, $item->{value}; } # 传递分组后的数据给模板并生成输出 my $report; $tt->process('test.tt', { grouped => \%grouped_data }, \$report) or die $tt->error(), "\n"; print $report;
2. 完成Template模板(test.tt)
基于分组后的数据,用两层循环即可实现预期格式的输出:
[% FOREACH file IN grouped.keys.sort %] [% file %]: [% FOREACH content IN grouped.$file %] [% content %] [% END %] [% END %]
说明
- Perl脚本新增的分组逻辑,将每个目标文件对应的所有
value值存入数组,避免模板中频繁判断文件归属。 - 模板通过外层循环遍历目标文件名,内层循环输出对应文件的所有内容,完全匹配预期输出格式。
内容的提问来源于stack exchange,提问作者varun kumar
相关产品推荐
相关产品推荐

