2011-11-01 196 views
0

我需要幫助解決這個問題,我從過去15天開始苦苦掙扎,請幫助我。我有xml文件,並且使用XML :: simple存儲在一個變量中。我通過模板工具包進行處理。我收到錯誤這樣爲什麼使用Template在FOREACH循環中出現錯誤?

$var1={ 
university=>{ 
     'name'=>'svu', 
     'location'=>'ravru', 
     'branch'=>{ 
       'electronics'=>{ 
          'student'=>[ 
            { 
            'name'=>'mikky', 
            'number'=>'12', 
             'semester'=>{ 
               'Number'=>'1', 
               'subjects'=>'7', 
               'rank'=>'1' 
               } 
              }, 
            { 
            'name'=>'vijju', 
            'number'=>'15', 
             'semester'=>[ 
              { 
              'number'=>'1', 
              'subjects'=>'7', 
              'rank'=>'10' 
               }, 
              { 
              'number'=>'1', 
              'subjects'=>'7', 
              'rank'=>'1' 
               } 
              ] 
              }, 
              { 
            'name'=>'shyam', 
            'number'=>'16', 
             'semester'=>[ 
              { 
              'number'=>'1', 
              'subjects'=>'7', 
              'rank'=>'2' 
               }, 
              { 
              'number'=>'2', 
              'subjects'=>'4', 
              'rank'=>'2' 
               } 
              ] 
              } 
             } 
             ] 
            } 
            }; 
      university=>{ 
       'name'=>'sku', 
       'location'=>'ANTP', 
        'branch'=>{ 
         'electronics'=>{ 
            'student'=>[ 
              { 
              'name'=>'xxx', 
              'number'=>'12', 
              'semester'=>{ 
                'Number'=>'3', 
                'subjects'=>'6', 
                'rank'=>'20' 
               } 
              }, 
            { 
            'name'=>'xxx', 
            'number'=>'6', 
             'semester'=>[ 
              { 
              'number'=>'1', 
              'subjects'=>'9', 
              'rank'=>'12' 
               }, 
              { 
              'number'=>'2', 
              'subjects'=>'4', 
              'rank'=>'2' 
               } 
              ] 
              } 
             } 
             ] 
            } 
            }; 
     'studentaddres'=>{ 
       'address'=>[ 
          { 
          'name'=>'mikky', 
          'number'=>'12', 
          'adress'=>' badvel,kadapa,a.p,india', 
          }, 

          { 
          'name'=>'vijju', 
          'number'=>'15', 
          'adress'=>' raipur,ananthapur,a.p,india', 
          }, 

          { 
          'name'=>'shyam', 
          'number'=>'16', 
          'adress'=>' raighad,rajsthan,india', 
          }, 
          ] 
         } 

(新評論:我有這樣的數據,如果我們看看深我對學生的元素相同的名稱和數量,也可以在地址元素,我還有一件事現在我需要在地址元素中搜索學生姓名和號碼,並獲取該學生的地址,有時候我使用不同號碼的同名姓名,因此我需要搜索學號和姓名以獲得學號。)

和我這樣處理

#!/usr/bin/perl 
use warnings; 
use strict; 
use Data::Dumper; 
use XML::Simple; 
use XML::Fast; 
use Template; 

my $xml = new XML::Simple; 
my $data = $xml->XMLin("data.xml"); 
print Dumper($data); 
my $template = Template->new(); 
my $filename = 'output.tex'; 
$template->process(\*DATA, $data, $filename) 
    || die "Template process failed: ", $template->error(), "\n"; 

system("pdflatex $filename"); 
__DATA__ 
\documentclass[a4paper,leqno,twoside]{article} 
\begin{document} 

[% FOREACH st IN university %] 
[% st.name %] 
[%st.location%] 
studentdata: 
[% FOREACH student IN st.branch.electronics.student %] 
Component type: [%+ student.name +%][%+ student.number +%] 
[% FOREACH semester IN student.semester %] 
[%+ semester.number +%] 
[%+ semester.subjects +%] 
[%+ semester.rank +%] 
[% END %] 
[% END %] 
[% END %] 

\end{document} 

但我得到不同的輸出,而不是我想要的。執行這個腳本後,當我有三個或更多的電子學學生,並且每個學生有兩個或更多的學期時,我就會得到輸出結果,只有我得到了。否則它打印任何東西只是打印學生數據:三次。例如,如果我有一個學生在大學一個學期在這種情況下它不給任何東西它打印這樣

 studentdata: 
      studentdata: 
      studentdata: 

爲什麼循環執行這樣的,我真的不能明白自己做錯了什麼贏for循環但我需要像這樣打印

name: 
     svu 
location: 
     ravru 
student data: 
    student name=xxx number=12 
    semester number=1 subjects=7 rank=2 
    student name=xxx number=15 
    semester number=1 subjects=7 rank=10 
semester number=2 subjects=4 rank=1 
student name=xxx number=16 
semester number=1 subjects=7 rank=2 
semester number=2 subjects=4 rank=2 

#!/usr/bin/perl 
use warnings; 
use strict; 
use Data::Dumper; 
use XML::Simple; 
use XML::Fast; 
use Template; 

my $studentaddres; 

    my $xml = new XML::Simple; 
my $data = $xml->XMLin("data.xml", ForceArray=>1); 
    print Dumper($data); 

my $template = Template->new(); 
    my $filename = 'output.tex'; 
    $template->process(\*DATA, $data, $filename) 
|| die "Template process failed: ", $template->error(), "\n"; 

$studentaddres->{by_student_number} 
= { map { $_->{number} => $_ } @{ $studentaddres->{address} }}; 

system("pdflatex $filename"); 
    __DATA__ 
\documentclass[a4paper,leqno,twoside]{article} 
    \begin{document} 

[% FOREACH st IN university %] 
    [% st.name %] 
    [%st.location%] 
    studentdata: 
    [% FOREACH student IN st.branch.electronics.student %] 
    Component type: [%+ student.name +%][%+ student.number +%] 

    [% address = studentaddres.by_student_number.item(student.number); 
    IF address %] 
[% address.adress %] 
[% END %] 
[% FOREACH semester IN student.semester %] 
    [%+ semester.number +%] 
    [%+ semester.subjects +%] 
    [%+ semester.rank +%] 
    [% END %] 
    [% END %] 
    [% END %] 

    \end{document} 

回答

3

首先,您的數據不是有效的perl。其次,通過散列迭代會給你一個(類似Java的)「入口」對象。所以'st'=> {key =>'name',value =>'svu'}。因此st.name不算什麼。

這更像是你想要的東西(或什麼工作,反正):

name: 
     [% university.name %] 
location: 
     [% university.location %] 
studentdata: 
    [%- FOREACH student IN university.branch.electronics.student %] 
     student name=[% student.name %] number=[% student.number %] 
     [%- FOREACH semester IN student.semester %] 
    semester number=[% semester.number %] subjects=[% semester.subjects 
      %] rank=[% semester.rank %] 
     [%- END -%] 
    [%- END -%] 

我不得不改變對學生的#12「學期」是一個數組和去利用「數字」。這是你有什麼:

'semester'=>{ 
      'Number'=>'1', 
      'subjects'=>'7', 
      'rank'=>'1' 
      } 

這就是我把它改爲:

'semester'=>[{ 
      'number'=>'1', 
      'subjects'=>'7', 
      'rank'=>'1' 
      }] 

沒有學期爲一個數組,你只是通過這種類型的事情迭代再次:

({ key => 'number', value => '1' } 
, { key => 'subjects', value => '7' } 
, { key => 'rank',  value => '1' } 
) 

而不一定(或甚至可能)按順序。

使用正確關閉$var1的數據,我把上面的代碼給我:

\documentclass[a4paper,leqno,twoside]{article} 
    \begin{document} 

name: 
     svu 
location: 
     ravru 
studentdata: 
     student name=xxx number=12 
    semester number=1 subjects=7 rank=1 
     student name=xxx number=15 
    semester number=1 subjects=7 rank=10 
    semester number=1 subjects=7 rank=1 
     student name=xxx number=16 
    semester number=1 subjects=7 rank=2 
    semester number=2 subjects=4 rank=2 
    \end{document} 

調試腳本,你可能要進行以下更改:

my $template = Template->new({ EVAL_PERL => 1 }); 

而且然後,在想要查看您要尋址的結構的位置,請執行以下操作:

[% RAWPERL %] 
use Data::Dumper(); 
print Data::Dumper->Dump([ $stash->get('semester') ], [ 'semester' ]), "\n"; 
[% END %] 

你會很快看到學期中的散列沒有數字,主題或排名字段。


(接聽評論)好吧,如果你有一些學生因爲有些地址沒有,你可以做到以下幾點:

[% IF student.address; 
    addr = student.address; %][%- 
    -%]Address: [% addr.lines.1 %] 
       [% addr.lines.2 %] 
       [% addr.city %], [% addr.state %] [% addr.zip %] 
[% END %] 

或者,如果你有地址哈希值,你可以做以下。

[% IF address_for_student.exists(student.number); 
    address = address_for_student.item(student.number); 
    %] 
... 
[% END %] 

(答題的新地址部分)

可以演示文稿之前按摩你的數據。這是我建議之前傳遞數據到表示層。 (這裏$studentaddres只是在藏匿結構的參考。)

$studentaddres->{by_student_number} 
    = { map { $_->{number} => $_ } @{ $studentaddres->{address} }} 
    ; 

然後,在表示層你可以這樣做:

[% address = studentaddres.by_student_number.item(student.number); 
    IF address %] 
    ... 
[% END %] 

在一般情況下,你應該有鏈接,您需要之前的到表示層,這使得表示層只是顯示數據的問題。

XML存儲您的模型。精細。 XML可以很好地處理樹,但不能很好地處理複雜的圖。所以如果你有複雜的關係(而且XML :: Simple不會知道關於這些的任何),你必須使用這種類型的算法模型:檢索→鏈接→顯示。你必須用YAML或JSON或從數據庫中取出行來做到這一點,所以鏈接階段對我來說是第二性質的。

表示層對於搜索是錯誤的層。它應該只處理0,1或許多或簡單情況的列表,如關係存在與否。

+0

我有15所大學,所以我寫了循環獲取所有大學的,我得到的所有價值觀,但我的問題是在第二個循環。我無法按照自己的想法獲得學生元素。如果一個學生和一個學期的電子學課程循環執行三次。如果我有兩個或兩個以上的學生和兩個或兩個以上的電子學期的學期打印完全。我不知道爲什麼這個問題。正如我所說的,@pavini, – pavani

+0

。 1)你的數據不好,2)你正在迭代哈希。由於有三把鑰匙,你繞了三圈。查看我對學生#12所做的更改。 – Axeman

+0

@pavini,看修改後的答案。 – Axeman