tags:

views:

2804

answers:

7

Hi all!

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

+5  A: 
$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 );
ysth
Thanks for your help ysth, i understand that the $line_Holder only holds the the last line of the file and i was doing some script that will hold all the data from the text file but i can't find a suitable code that has its objective. Glad you gave me that idea on this Slurp. It can now see the parsed perl equivalent, and i can access all of its data using that code. Thank you very much!
newbee_me
+2  A: 

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.

depesz
The regex isn't necessary—the value of the assignment statement is the same as the right-hand side of the assignment.
nohat
+2  A: 

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.

Ricky Morse
+1. Data::Dump is basically Data::Dumper done right. It avoids assignments to $VAR1 etc. and fixes several tricky edge cases at the same time.
j_random_hacker
A: 

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

e.g.

$Data::Dumper::Varname = "foo";
my $string = Data::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.

Ether
A: 

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 };
billg
A: 

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

miniradlader
A: 

thanks for the help.

Regards, Aishwarya.V

Aishwarya.V