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

Hello Monks, I kind of need your help. I have the following code:
use XML::Simple; use Data::Dumper; my $hash= { 'root' => { 'item1' => { 'item1a' => 'n1', 'item1b'=>'jh' } } }; my $xs = new XML::Simple; my $xml = $xs->XMLout($hash, NoAttr => 1, RootName=>undef,); print Dumper $xml;
This is outputting :
<root> <name>item1</name> <item1a>n1</item1a> <item1b>jh</item1b> </root>
But I want the xml to be ALL nested like that:
<root> <item1> <item1a>n1</item1a> <item1b>jh</item1b> </item1> </root>
What do you think I should do?? Please help I am stuck :S Thanks

Replies are listed 'Best First'.
Re: XMLOut in XML::Simple returning unwanted xml format
by haukex (Archbishop) on May 21, 2018 at 14:47 UTC
    What do you think I should do?

    I think you shouldn't use XML::Simple! There are lots of issues with that module, especially with writing XML. There are several much better modules for XML handling, such as XML::Rules (which can often replace XML::Simple for reading XML) or XML::Twig, but for writing XML, personally I like to use XML::LibXML because it gives me the most control. (Update: Note the following makes some assumptions about the input data format, such as that you don't have any arrayrefs, as well as the output format, because the sample data you've provided is pretty short, and you haven't explained what rules should be used for conversion. But I hope it's a starting point.)

    use warnings; use strict; use XML::LibXML; my $hash = { 'root' => { 'item1' => { 'item1a' => 'n1', 'item1b'=>'jh' } } }; my $dom = XML::LibXML::Document->createDocument(); # recursively convert hashes to elements my $frag = $dom->createDocumentFragment(); my $hash2el; $hash2el = sub { my ($n,$h) = @_; for my $key (sort keys %$h) { my $el = $dom->createElement($key); if (ref $h->{$key} eq 'HASH') { $hash2el->($el, $h->{$key}) } else { $el->appendText( ''.$h->{$key} ) } $n->appendChild($el); } }; $hash2el->($frag, $hash); # either a single root node, or multiple nodes in a new root my @roots = $frag->nonBlankChildNodes(); if (@roots==1) { $dom->setDocumentElement( $roots[0] ); } elsif (@roots>1) { my $root = $dom->createElement('root'); $root->appendChild($frag); $dom->setDocumentElement( $root ); } print $dom->toString(1); __END__ <?xml version="1.0"?> <root> <item1> <item1a>n1</item1a> <item1b>jh</item1b> </item1> </root>
      Maybe I can use that for more complicated situations. Thank you for the insight I will keep it in mind

        You should get used to reading documentation, the first line of the module synopsis:

        PLEASE DO NOT USE THIS MODULE IN NEW CODE.

Re: XMLOut in XML::Simple returning unwanted xml format
by salva (Canon) on May 21, 2018 at 15:12 UTC
    You would also like to check XML::FromPerl which allows one to generate XML in a straight forward manner using Perl data structures to describe its contents.
Re: XMLOut in XML::Simple returning unwanted xml format
by Veltro (Hermit) on May 21, 2018 at 15:03 UTC

    You can use KeyAttr=>{Item1=>'name'}

    use XML::Simple; use Data::Dumper; my $hash= { 'root' => { 'item1' => { 'item1a' => 'n1', 'item1b'=>'jh' } } }; my $xs = new XML::Simple( ); my $xml = $xs->XMLout($hash, NoAttr => 1, RootName=>undef, KeyAttr=>{I +tem1=>'name'} ); print Dumper $xml;

    Or you do what haukex said

      This was actually what I needed since it was just a simple map needed.Thank you!