为什么使用模板在 FOREACH 循环中出现错误?

发布于 2024-12-13 01:04:39 字数 8087 浏览 1 评论 0原文

我需要帮助解决这个问题,过去 15 天我一直在苦苦挣扎,请帮助我。我有 xml 文件,并使用 XML::simple 存储在变量中。我是通过模板工具包进行处理的。我收到这样的错误

$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: Three times 。例如,如果我有一个学生在大学读了一个学期,在这种情况下,它不会给出任何像这样打印的东西,

       studentdata:
           studentdata:
            studentdata:

为什么 for 循环会这样执行,我无法理解 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}

I need help with this problem, I am struggling from last 15days please help me.I have xml file and I stored in a variable using XML::simple. I processed through template toolkit. I am getting error like this

$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',
                            },
                          ]
                       }

(New comment: I have the data like this, If We look into deep I have the same name and number in student element and also in address element, I have one more thing adress in address element. now I need to search student name and number in address element and get the address of that student. Some times I have same names with different numbers so I need to search both number and name for student address.)

and I processed like this

#!/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}

But I getting Different output rather than what I want. After executing this script I am getting output when I have three or more students in electronics and two or more semesters for each student then only I am getting. otherwise it does print any thing just printing studentdata: three times . for example if I have one student with one semester in university at that situation it doesn't give any thing it printing like this

       studentdata:
           studentdata:
            studentdata:

why for loop is executing like that, I can't understand really what wrong win the for loop but I need to print like this

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}

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

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

发布评论

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

评论(1

可爱咩 2024-12-20 01:04:39

首先,您的数据不是有效的 perl。其次,迭代哈希会为您提供一个(类似 Java 的)“条目”对象。所以 'st' => { 键=> '名称',值=> '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 或许多或简单情况(例如关系存在或不存在)的列表。

First of all, your data is not valid perl. Secondly, iterating through a hash gives you a (Java-like) "entry" objects. So 'st' => { key => 'name', value => 'svu' }. Thus st.name is nothing.

This is more like what you want (or what works, anyway ):

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 -%]

And I had to change 'semester' on student #12 to be an array and de-capitalize 'number'. This is what you had:

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

This is what I changed it to:

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

Without semester as an array, you were just iterating through this type of thing again:

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

And not necessarily (or even likely) in that order.

Using a properly closed $var1 as the data, the code I put above gives me:

   \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}

To debug your script, you might want to make the following changes:

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

And then, where you want to see the structure that you're addressing, do this:

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

You'll quickly see when the hash in semester has no number, subjects, or rank fields.


(Answering comment) Well, if you have some students with addresses as some without, you could do the following:

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

Or if you had a hash of addresses, you could do the following.

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

(Answering new address part of question)

You can massage your data before presentation. This is what I suggest before passing the data to the presentation layer. (Here $studentaddres is just a reference to the structure in the stash.)

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

Then, in the presentation layer you can just do this:

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

In general, you should have the links that you need prior to the presentation layer, that makes the presentation layer just a matter of displaying the data.

XML stores your model. Fine. XML does trees just fine, but doesn't do complex graphs too well. So if you have complex relationships (and XML::Simple is not going to know anything about those) you have to use this type of algorithmic model: retrieve → link → display. You have to do this with YAML or JSON or even rows pulled from a database, so the link stage is second-nature to me.

The presentation layer is the wrong layer for searching. It should just handle lists of 0, 1, or many or simple cases like relationship exists-or-not.

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