in reply to Re: Perl and XML
in thread Perl and XML

Hey,
The Data I provided as Perl Hash is a sample of what I have. And I need to convert it the other way round, from Hash to XML and XML::Simple will just convert it to simple XML but then the problem of illegal tags <1>,<2>,<3> crops up so i can't use XML::Simple unless it allows me to make that changes.
Bugz

Replies are listed 'Best First'.
Re^3: Perl and XML
by shmem (Chancellor) on Apr 29, 2008 at 17:58 UTC

    Did you lather, rinse, repeat? You would have found out that the data structure you want with XML::Simple is as follows:

    $FIELDS = { data => { Node => [ { No => '1', Label => 'AA', Type => { content => 'Module' }, File => { content => 'Sample1.pl'}, Description => { }, }, { No => '2', Label => 'BB', Type => { content => 'Methods' }, File => { content => 'Sample1.pl' }, Description => { content => 'Initiator' }, }, { No => '3', Label => 'CC', Type => { content => 'Methods' }, File => { content => 'Sample2.pl' }, Description => { content => 'Destructor' }, Value => [ { No => '1', content => 'Ignore', }, { No => '2', content => 'Retry', }, { No => '3', content => 'Abort', } ], } ] } };

    Output:

    <opt> <data> <Node Label="AA" No="1"> <Description></Description> <File>Sample1.pl</File> <Type>Module</Type> </Node> <Node Label="BB" No="2"> <Description>Initiator</Description> <File>Sample1.pl</File> <Type>Methods</Type> </Node> <Node Label="CC" No="3"> <Description>Destructor</Description> <File>Sample2.pl</File> <Type>Methods</Type> <Value No="1">Ignore</Value> <Value No="2">Retry</Value> <Value No="3">Abort</Value> </Node> </data> </opt>

    Getting rid of the outer <opt> tag is left as an exercise to the reader.

    As dragonchild wrote above, you need to transform your hash so as to fit the module you are using.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Hey Shmem
      I think I made my questions confusing. I apologise. Let me rephrase my question: I have a Perl Hash as shown
      $FIELDS = { 'AA' => { 'Description' => '', 'Type' => 'Module', 'File' => 'Sample1.pl', }, 'BB' => { 'Description' => 'Initiator', 'Type' => 'Methods', 'File' => 'Sample1.pl', }, 'CC' => { 'Description' => 'Destructor', 'Type' => 'Methods', 'File' => 'Sample2.pl', 'Values' => { '1' => 'Ignore', '2' => 'Retry', '3' => 'Abort' } } },
      I need to convert it to a Valid XML File. I tried using XML::Simple, but it changes '1' to <1> which is invalid XML Tag.
      I checked CPAN docs on XML::Simple, and while they talk about KeyAttr ValueAttr, I am unsure How I can do what you and dragonchild suggest.
      I wanted to know if I could handle this conversion better using XML::Writer or XML::Twig and if so how?
      Thanks,
      Bugz
        Let me rephrase my question:

        You don't rephrase, you just repeat the contents of your OP... ;)

        I am unsure How I can do what you and dragonchild suggest.

        Did you even try? You provided me with a hash; I showed you the correct structure which would produce the output you described as desired. You have to transform your original hash, either in-place or by stuffing members into another temporary structure. What pieces of the hash transformation are difficult for you?

        Okay, here' a complete working example. Since you provide sample data which is a bit inconsistent compared to the expected output (there's no structure member for the "No" attribute, so I just deduce them from the sorted hash keys) you will have to adapt the following for your real data, I guess.

        use XML::Simple; # your structure $FIELDS = { 'AA' => { 'Description' => '', 'Type' => 'Module', 'File' => 'Sample1.pl', }, 'BB' => { 'Description' => 'Initiator', 'Type' => 'Methods', 'File' => 'Sample1.pl', }, 'CC' => { 'Description' => 'Destructor', 'Type' => 'Methods', 'File' => 'Sample2.pl', 'Values' => { '1' => 'Ignore', '2' => 'Retry', '3' => 'Abort', } } }; # hash transformation, in-place my $c; for my $key (sort keys %$FIELDS) { $FIELDS->{$key}->{Label} = $key; $FIELDS->{$key}->{No} = ++$c; for my $label (qw(Description Type File)) { $FIELDS->{$key}->{$label} = { content => $FIELDS->{$key}->{$la +bel} }; } if (exists $FIELDS->{$key}->{Values}) { my $values_hash = $FIELDS->{$key}->{Values}; $FIELDS->{$key}->{Values} = [ map { { No => $_, content => $values_hash->{$_} } } sort keys %$values_hash ]; } } # output the XML print XMLout( { data => { Node => [ map $FIELDS->{$_}, sort keys %$FIELDS ] } } ); __END__ <opt> <data> <Node Label="AA" No="1"> <Description></Description> <File>Sample1.pl</File> <Type>Module</Type> </Node> <Node Label="BB" No="2"> <Description>Initiator</Description> <File>Sample1.pl</File> <Type>Methods</Type> </Node> <Node Label="CC" No="3"> <Description>Destructor</Description> <File>Sample2.pl</File> <Type>Methods</Type> <Values No="1">Ignore</Values> <Values No="2">Retry</Values> <Values No="3">Abort</Values> </Node> </data> </opt>

        Hope that helps. I won't repeat the example for XML::Writer or XML::Twig; their requirements for input data might be different. But AFAIK there's no module which produces valid XML from your hash as is.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}