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

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

Replies are listed 'Best First'.
Re^5: Perl and XML
by shmem (Chancellor) on Apr 29, 2008 at 22:17 UTC
    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}