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

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}

Replies are listed 'Best First'.
Re^4: Perl and XML
by Bugz (Acolyte) on Apr 29, 2008 at 19:48 UTC
    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}