themonk has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

Want to convert txt file to xm,using xml::simple.

Hash of hash is not forming correctly. Can anyone please guide me to resolve, the root cause of mal-forming of hash.

use Data::Dumper; my $path; my @data; my $final = {}; while (<DATA>){ last if /^__END__$/; # stop when __END__ is encountered s/\n//gsi; s/=/./gsi; push (@data,$_); } foreach (@data){ print "$_ \n"; createHash($_); } print Dumper(\$final); sub createHash{ my $val = shift; my @x = split('\.',$val); my $i = 0; my $f = {}; while($i < scalar(@x)){ $f->{$x[$i+1]} = '['.$x[$i+2].']'; if(exists($final->{$x[$i]})){ print "second\n"; ($final->{$x[$i]}, $f); } else{ print "first\n"; $final->{$x[$i]} = ($final->{$x[$i]}, $f); } $i = $i+3; #print Dumper(\$final); } } use XML::Simple; $path = 'text2xml.xml'; open my $fh, '>:encoding(iso-8859-1)', $path or die "open($path): $!"; XMLout($final, OutputFile => $fh); __DATA__ a.b='xyz' a.c='abc' d='def' a.e='ghi' __END__ ## expected output <a> <b>xyz</b> <c>abc</c> <e>ghi</e> </a> <d>de</d>

Thanks in advance.

Replies are listed 'Best First'.
Re: Ill-formed hash of hash - to convert text to xml
by toolic (Bishop) on Jul 20, 2015 at 16:35 UTC
Re: Ill-formed hash of hash - to convert text to xml
by AnomalousMonk (Archbishop) on Jul 20, 2015 at 23:15 UTC

    Further to toolic's reply:

    if(exists($final->{$x[$i]})){ print "second\n"; ($final->{$x[$i]}, $f); } else{ print "first\n"; $final->{$x[$i]} = ($final->{$x[$i]}, $f); }
    The statement
        ($final->{$x[$i]}, $f);
    does nothing. What do you expect it to do?

    The statement
        $final->{$x[$i]} = ($final->{$x[$i]}, $f);
    is a bit more complex. It evaluates the list  ($final->{$x[$i]}, $f) in the scalar context imposed by the scalar  $final->{$x[$i]} on the LHS of the assignment. I doubt this statement does what you expect. Please see the Context tutorial, in particular the "Context clash" section.

    c:\@Work\Perl>perl -wMstrict -MData::Dumper -le "my $final = { qw(a 1 b 2 c 3), d => [ 9, 8, 7 ] }; my @x = qw(a b c); print 'data to start'; print Dumper $final; print Dumper \@x; ;; my $f = 'ZOT'; ;; print 'void-context expression'; ($final->{$x[1]}, $f); print Dumper $final; ;; print 'assign list in scalar context'; $final->{$x[1]} = ($final->{$x[1]}, $f); print Dumper $final; " Useless use of hash element in void context at -e line 1. Useless use of hash element in void context at -e line 1. Useless use of private variable in void context at -e line 1. data to start $VAR1 = { 'c' => '3', 'a' => '1', 'b' => '2', 'd' => [ 9, 8, 7 ] }; $VAR1 = [ 'a', 'b', 'c' ]; void-context expression $VAR1 = { 'c' => '3', 'a' => '1', 'b' => '2', 'd' => [ 9, 8, 7 ] }; assign list in scalar context $VAR1 = { 'c' => '3', 'a' => '1', 'b' => 'ZOT', 'd' => [ 9, 8, 7 ] };
    Please pay attention to the warning messages generated by warnings. (The "Useless use of..." messages will have useful line numbers associated with them if you run your code from a script rather than from the command line as I have.)

    I think there may be other problems with the script, but this should get you going. Perhaps also see Perl Data Structures Cookbook.


    Give a man a fish:  <%-(-(-(-<

Re: Ill-formed hash of hash - to convert text to xml
by AnomalousMonk (Archbishop) on Jul 21, 2015 at 06:16 UTC

    You have re-posted an apparent exact duplicate of the OP of this thread. Please do not re-post such duplicates. Please respond in this thread as to how the advice offered here has or has not helped you, and as to specific new difficulties you may be facing.


    Give a man a fish:  <%-(-(-(-<

      Hi,

      I made some changes as per my understanding, but i couldn't make changes in the code to reflect as per requirement.

      ... if(exists($final->{$x[$i]})){ print "second\n"; $final->{$x[$i]} = ($final->{$x[$i]}, $f); #### i need to push th +e $f into $final. } ...

      Current output:

      $VAR1 = \{ 'a' => { 'b' => 'abc' } };

      Expected Output:

      $VAR1 = \{ 'a' => { 'b' => 'abc' }, { 'c' => 'xyz' } };

Re: Ill-formed hash of hash - to convert text to xml
by NetWallah (Canon) on Jul 21, 2015 at 06:58 UTC
    Try this alternative code:
    use strict; use warnings; use Data::Dumper; my $hash; while (<DATA>){ my ($left,$val) = split /=/,$_ or next; my ($first,@levels) = split /\./,$left; my $str="\$hash->{$first}"; for my $last_level(@levels){ $str .= "{$last_level}" } eval "$str=$val"; } print Dumper \$hash; __DATA__ a.b='xyz' a.c='abc' d='def' a.e='ghi'
    If using for production, you may want to sanitize the data before the string eval.
    Output:
    $VAR1 = \{ 'a' => { 'e' => 'ghi', 'c' => 'abc', 'b' => 'xyz' }, 'd' => 'def' };

            "Despite my privileged upbringing, I'm actually quite well-balanced. I have a chip on both shoulders."         - John Nash