Search code examples
xmlperlperl-module

Unable to loop inside a call to XML::Generator


I am trying to use a for loop to put each item from array @cpuinfo into a separate <cpu> element in an XML document using XML::Generator.

# @cpuinfo contain cpu information of multiple cpu's
use XML::Generator;

my $gen = XML::Generator->new( 'escape' => 'always', 'pretty' => 10 );

my $xml = $gen->servers(
   $gen->server(

      $gen->cpuinfo(

         foreach $r (@cpuinfo){
            $gen->cpu;
            (  {  $gen->cpu( @cpuinfo[$r] );
               }
            )
         }

      )
   ),
);

Solution

  • You don't seem to be at all familiar with Perl, and this isn't the place for a tutorial, but most languages don't allow you to put an executable loop inside a parameter list. What you need is a call to map, which "maps" one list of data into another. In this case it maps the list of text items in @cpuinfo to a list of XML::Generator objects that each represent a <map> element

    Remember that you must always use strict and use warnings 'all' at the top of every Perl program that you write, and declare every variable with my as close as possible to its first point of use, preferably at the point it is defined

    use strict;
    use warnings 'all';
    
    use XML::Generator;
    
    my @cpuinfo = qw/ A B C /;
    
    my $gen = XML::Generator->new( escape => 'always', pretty => 2 );
    
    my $xml = $gen->servers(
        $gen->server(
            $gen->cpuinfo(
                map { $gen->cpu($_) } @cpuinfo
            )
        )
    );
    
    print $xml, "\n";
    

    output

    <servers>
      <server>
        <cpuinfo>
          <cpu>A</cpu>
          <cpu>B</cpu>
          <cpu>C</cpu>
        </cpuinfo>
      </server>
    </servers>