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

Hello, I'm trying to use XML::Simple to serialize datas into xml file. (XMLOut) my data structure:
my $TestRun= { 'SuccessfulTests' => [ { 'Test' => { 'name' => "toto" } }, { 'Test' => { 'name' => "titi" } } ], 'FailedTests' => [ { 'Test' => { 'name' => "tutu" } }, { 'Test' => { 'name' => "tete" } } ] };
And the xml structure I would like to have:
<TestRun> <SuccessfulTests> <Test> <Name>toto</Name> </Test> <Test> <Name>titi</Name> </Test> </SuccessfulTests> <FailedTests> <Test> <Name>tutu</Name> </Test> <Test> <Name>tete</Name> </Test> </FailedTests> </TestRun>
my $xml = new XML::Simple; my $dec = '<?xml version="1.0" encoding="utf-8"?>'; print $xml->XMLout($VAR2, XMLDecl => $dec, keyattr => [], RootName => +'TestRun');
result:
<?xml version="1.0" encoding="utf-8"?> <TestRun> <SuccessfulTests> <Test name="toto"/> </SuccessfulTests> <SuccessfulTests> <Test name="titi"/> </SuccessfulTests> <FailedTests> <Test name="tutu"/> </FailedTests> <FailedTests> <Test name="tete"/> </FailedTests> </TestRun>
Unfortunatley, I did not succeeded. I do not want SuccessfulTests and FailedTests to be repeated. Any help would be appreciated. Thx, Totorototo.

Replies are listed 'Best First'.
Re: XML::Simple XMLout
by Anonymous Monk on Dec 19, 2014 at 15:25 UTC

    It takes some fiddling, but it turns out to be possible: KeyAttr=>{Test=>'name'}, GroupTags=>{FailedTests=>'Test',SuccessfulTests=>'Test'}, NoAttr=>1, RootName=>'TestRun'

    However, the solution is likely to break for the smallest change in the data structure; this is one of the problems of XML::Simple. I think the module is fine for reading simple configuration files that have been designed to work for it, but for anything beyond that, especially writing XML when you have a specific structure requirement, it starts being too finicky and brittle. One commonly recommended alternative module is XML::Twig, but there are plenty more.

      It works fine! Thx! ps: I actually use XML::Simple just because I don't want to manage to many dependencies.

        Well ok, but don't be surprised if it breaks when your data structure changes slightly, XML::Simple gets upgraded, etc. ... you've been warned ;-)

        Plus, plenty of other XML modules have about the same amount of dependencies as XML::Simple, so I don't see that as a good reason not to switch to a more powerful XML module.

      Hello, It's me again! :) I have changed the data structure just a little bit to something alittle bit more complex, but not too much! Here is my updated struc:
      my $VAR2 = { 'SuccessfulTests' => [ { 'Test' => { 'id' => '1', 'name' => 'toto' } }, { 'Test' => { 'id' => '1', 'name' => 'titi' } } ], 'FailedTests' => [ { 'FailedTest' => { 'id' => '1', 'name' => 'tutu', 'svgs' => [ { 'svg' => '\tutu_1.svg' } ] } }, { 'FailedTest' => { 'id' => '1', 'name' => 'tete', 'svgs' => [ { 'svg' => '\tete_1.svg' }, { 'svg' => '\tete_2.svg' } ] } } ] };
      What I would like to get is something like this:
      <?xml version="1.0" encoding="utf-8"?> <TestRun> <SuccessfulTests> <Test name="toto"/> </SuccessfulTests> <SuccessfulTests> <Test name="titi"/> </SuccessfulTests> <FailedTests> <Test name="tutu"/> <svgs> <svg>\tutu_1.svg</svg> </svgs> </FailedTests> <FailedTests> <Test name="tete"/> <svgs> <svg>\tete_1.svg</svg> <svg>\tete_2.svg</svg> </svgs> </FailedTests> </TestRun>
      I have tried to use 'GroupTags' to do this but unfortunately I have not succeded. Any help would be appreciated, again :) Thx!
Re: XML::Simple XMLout
by Anonymous Monk on Dec 19, 2014 at 21:20 UTC