newbee_me
newbee_me

Reputation: 31

How do I convert Data::Dumper output back into a Perl data structure?

I was wondering if you could shed some lights regarding the code I've been doing for a couple of days.

I've been trying to convert a Perl-parsed hash back to XML using the XMLout() and XMLin() method and it has been quite successful with this format.

#!/usr/bin/perl -w
use strict;

# use module
use IO::File;
use XML::Simple;
use XML::Dumper;
use Data::Dumper;
my $dump = new XML::Dumper;

my ( $data, $VAR1 );

Topology:$VAR1 = {  
   'device' => {  
    'FOC1047Z2SZ' => {  
      'ChassisID' => '2009-09',  
      'Error' => undef,  
      'Group' => {  
        'ID' => 'A1',  
        'Type' => 'Base'  
      },  
      'Model' => 'CATALYST',  
      'Name' => 'CISCO-SW1',  
      'Neighbor' => {},  
      'ProbedIP' => 'TEST',  
      'isDerived' => 0  
    }  
  },  
  'issues' => [  
    'TEST'  
  ]  
};  

# create object  
my $xml = new XML::Simple (NoAttr=>1,  
                           RootName=>'data',     
                           SuppressEmpty => 'true');  

# convert Perl array ref into XML document  
$data = $xml->XMLout($VAR1);  

#reads an XML file  
my $X_out = $xml->XMLin($data);  

# access XML data  
print Dumper($data);  
print "STATUS: $X_out->{issues}\n";  
print "CHASSIS ID: $X_out->{device}{ChassisID}\n";  
print "GROUP ID: $X_out->{device}{Group}{ID}\n";  
print "DEVICE NAME: $X_out->{device}{Name}\n";  
print "DEVICE NAME: $X_out->{device}{name}\n";  
print "ERROR: $X_out->{device}{error}\n";  

I can access all the element in the XML with no problem.

But when I try to create a file that will house the parsed hash, problem arises because I can't seem to access all the XML elements. I guess, I wasn't able to unparse the file with the following code.

#!/usr/bin/perl -w
use strict;
#!/usr/bin/perl

# use module
use IO::File;  
use XML::Simple;  
use XML::Dumper;  
use Data::Dumper;  
my $dump = new XML::Dumper;  

my ( $data, $VAR1, $line_Holder );

#this is the file that contains the parsed hash  
my $saveOut = "C:/parsed_hash.txt";  
my $result_Holder = IO::File->new($saveOut, 'r');  
while ($line_Holder = $result_Holder->getline){  
    print $line_Holder;  
}  

# create object  
my $xml = new XML::Simple (NoAttr=>1, RootName=>'data', SuppressEmpty => 'true');  
# convert Perl array ref into XML document  
$data = $xml->XMLout($line_Holder);  
#reads an XML file  
my $X_out = $xml->XMLin($data);  

# access XML data  
print Dumper($data);  
print "STATUS: $X_out->{issues}\n";  
print "CHASSIS ID: $X_out->{device}{ChassisID}\n";  
print "GROUP ID: $X_out->{device}{Group}{ID}\n";  
print "DEVICE NAME: $X_out->{device}{Name}\n";  
print "DEVICE NAME: $X_out->{device}{name}\n";  
print "ERROR: $X_out->{device}{error}\n";  

Do you have any idea how I could access the $VAR1 inside the text file?

Regards,
newbee_me

Upvotes: 2

Views: 12848

Answers (6)

Ether
Ether

Reputation: 53966

You can configure the variable name used in Data::Dumper's output with $Data::Dumper::Varname.

Example

use Data::Dumper
$Data::Dumper::Varname = "foo";
my $string = Dumper($object);
eval($string);

...will create the variable $foo, and should contain the same data as $object. If your data structure is complicated and you have strange results, you may want to consider Storable's freeze() and thaw() methods.

Upvotes: 1

miniradlader
miniradlader

Reputation: 11

Please use dump module as a replacement for Data::Dumper

Upvotes: 1

billg
billg

Reputation: 11

This has worked for me, for hashes of hashes. Perhaps won't work so well with structures which contain references other structures. But works well enough for simple structures, like arrays, hashes, or hashes of hashes.

 open(DATA,">",$file);
 print DATA Dumper(\%g_write_hash);
 close(DATA);

 my %g_read_hash = %{ do $file };

Upvotes: 1

Ricky Morse
Ricky Morse

Reputation: 488

You might want to look at the Data::Dump module as a replacement for Data::Dumper; its output is already ready to re-eval back.

Upvotes: 5

user80168
user80168

Reputation:

Basically to load Dumper data you eval() it:

use strict;
use Data::Dumper;
my $x = {"a" => "b", "c"=>[1,2,3],};
my $q = Dumper($x);
$q =~ s{\A\$VAR\d+\s*=\s*}{};
my $w = eval $q;
print $w->{"a"}, "\n";

The regexp (s{\A\$VAR\d+\s*=\s*}{}) is used to remove $VAR1= from the beginning of string.

On the other hand - if you need a way to store complex data structure, and load it again, it's much better to use Storable module, and it's store() and retrieve() functions.

Upvotes: 4

ysth
ysth

Reputation: 98378

$data = $xml->XMLout($line_Holder); 

$line_Holder has only the last line of your file, not the whole file, and not the perl hashref that would result from evaling the file. Try something like this:

my $ref = do $saveOut;

The do function loads and evals a file for you. You may want to do it in separate steps, like:

use File::Slurp "read_file";
my $fileContents = read_file( $saveOut );
my $ref = eval( $fileContents );

Upvotes: 5

Related Questions