2010-11-04 51 views
0

這是我在Perl中使用Template Toolkit編寫的東西,但它更像是一個通用算法問題。我的基本問題是,給定的數據結構是這樣的:構建「內省」嵌套html表

my @array = (
    [qw /00 01/], 
    [qw /10/], 
    [qw /20 21/], 
    [qw /30 31 32 33 /], 
); 

我需要像這樣輸出(簡化圖):

<00> 
    <10> 
    <20> <30>(00/10/20/30)</30> <31>(00/10/20/31)</31> 
     <32>(00/10/20/32)</32> <33>(00/10/20/30)</33> 
    </20> 
    <21> <30>(00/10/21/30)</30> <31>(00/10/21/31)</31> 
     <32>(00/10/21/31)</32> <33>(00/10/21/31)</33> 
    </21> 
    </10> 
</00> 
<01> 
    <10> 
    <20> <30>(01/10/20/30)</30> <31>(01/10/20/31)</31> 
     <32>(01/10/20/32)</32> <33>(01/10/20/33)</33> 
    </20> 
    <21> <30>(01/10/21/30)</30> <31>(01/10/21/31)</31> 
     <32>(01/10/21/32)</32> <33>(01/10/21/33)</33> 
    </21> 
</10> 
</01> 

這是屬於嵌套HTML表格的簡化示例實際產出。中心節點處的路徑實際上是要調用另一個子例程以使用數據填充嵌套表的參數。我相當肯定原始數組結構的轉置是有用的,所以我寫了Array::Transpose::Ragged並在今天早些時候在CPAN上發佈了它。

我管理一個從內部到外部構建嵌套結構的實現(使用perl的Template Toolkit - 見下文),但是當我到達結構的外部部分時,我不再有機會填充中央節點需要的數據。下面是它的價值是實現:

爲了興趣,我想我應該把TT版本:

[% SET inner = "(path data should go here)" %] 
[% MACRO process_groups(line, inner) BLOCK %] 
[% FOREACH l IN line %] 
<[% l %]>[% inner %]</[% l %]> 
[% END %] 
[% END %] 
[% WHILE (x = records.pop) %] 
[% inner = process_groups(x, inner) %] 
[% END %] 
[% inner %] 

對我應該採取得到這個權利

更新的方法有什麼建議的接受答案。有點棘手,因爲TT心不是相當的Perl作爲靈活,但這裏有雲:

#!/usr/bin/env perl 
use warnings; 
use strict; 
use Template; 
my $template = Template->new(); 
my @array = (
    [ qw/00 01/ ], [ qw/10/ ],[ qw/20 21/ ], [ qw/30 31 32 33/ ]); 
my $stash = { records => \@array, }; 
$template->process(\*DATA, $stash) || die $template->error(), "\n"; 

__END__ 
[% MACRO print_output(data, path_elements) BLOCK; %] 
[% current = data.0; remaining = data.slice(1); %] 
[% FOREACH d IN current %] 
<[% d %]> 
[% IF remaining.size > 0 %] 
[% path_elements.push(d); print_output(remaining, path_elements); %] 
[% SET discard = path_elements.pop %] 
[% ELSE %] 
([% path_elements.join('/') _ '/' _ d %]) 
[% END %] 
</[% d %]> 
[% END %] 
[% END %] 
[% SET path = []; print_output(records, path) %] 

更妙的是這裏是在TT的實際嵌套表結構:

[% MACRO print_output(data, path_elements) BLOCK; %] 
<table> <tr> 
[% current = data.0; remaining = data.slice(1); %] 
[% FOREACH d IN current %] 
<th>[% d %]</th> 
[% END %] </tr> 
<tr> 
[% FOREACH d IN current %] 
[% IF remaining.size > 0 %] 
<td id="[% d %]">[% path_elements.push(d); print_output(remaining, path_elements); %]</td> 
[% SET discard = path_elements.pop %] 
[% ELSE %] 
<td>([% path_elements.join('/') _ '/' _ d %])</td> 
[% END %] 
[% END %] 
</tr></table> 
[% END %] 
[% SET path = []; print_output(records, path) %] 
+0

這基本上是與格式列表組成的問題,對不對? – Axeman 2010-11-04 15:55:28

回答

1

不知道我理解中的完整的上下文您正在使用,但這裏的問題一般刺:

use strict; 
use warnings; 

my @array = (
    [ qw/00 01/ ], 
    [ qw/10/ ], 
    [ qw/20 21/ ], 
    [ qw/30 31 32 33/ ], 
); 
print_output(\@array); 

sub print_output { 
    my ($data, @path_elements) = @_; 
    my $level = @path_elements; 
    my ($current, @remaining) = @$data; 
    for my $d (@$current){ 
     print ' ' x $level, "<$d>\n";  
     if (@remaining){ 
      print_output(\@remaining, @path_elements, $d);   
     } 
     else { 
      print ' ' x ($level + 1), "(", join('/', @path_elements, $d), ")\n"; 
     } 
     print ' ' x $level, "</$d>\n"; 
    } 
} 
1

如果你想有一個模板工具包解決方案,請參閱下文。

Perl代碼:

use strict; 
use Template; 

my @array = (
    [qw /00 01/], 
    [qw /10/], 
    [qw /20 21/], 
    [qw /30 31 32 33/], 
); 

my $tt = Template->new(POST_CHOMP => 1); 

$tt->process('template.tt', { DATA => \@array }) or die "TT Error : " . $tt->error(); 

TT模板(固定)(template.tt):

[% BLOCK display -%] 
    [% arr = DATA.$i %] 
    [% IF i == DATA.max %] 
     [% FOREACH t IN arr -%] 
     <[% t %]> 
      [% tmp_c = c.substr(1) %] 
      [% "($tmp_c/$t)" %] 
     </[% t %]> 
     [% END %] 
    [% ELSE %] 
     [% FOREACH t IN arr -%] 
     <[% t %]> 
      [% INCLUDE display i = i+1, c = "$c/$t" %] 
     </[% t %]> 
     [% END -%] 
    [% END %] 
[% END -%] 

[% INCLUDE display i = 0, c = '' %] 
+0

這不太對。內在的東西是作爲原始數組最底層元素的連接而出現的,它應該是回到頂端的路徑。否則,謝謝:) – singingfish 2010-11-05 02:07:25