Hi,

I'm having a problem formatting the output of XMLout, and my XML file must have a specific format.

Here is my code that generates the data hash ref and then attempts to create an XML file:

#!/usr/bin/perl use strict; use warnings FATAL => 'uninitialized'; use XML::Simple qw(:strict); use Data::Dumper; $| = 1; my %ref; # create 1st node push(@{$ref{'node'}},{ 'id' => 'net_1.2.3.0', 'desc' => 'network', }); # create 2nd node push(@{$ref{'node'}},{ 'id' => 'ip_1.2.3.4', 'desc' => 'ipaddr', }); my $xmlParser = XML::Simple->new(); my $fh;open $fh,'>','/tmp/testfile.xml' or die "$!"; $xmlParser->XMLout(\%ref,( 'XMLDecl' => '<?xml version="1.0" encoding="utf-8"?>', 'NoAttr' => 0, 'KeepRoot' => 0, 'RootName' => 'test', 'OutputFile' => $fh, 'AttrIndent' => 1, 'KeyAttr' => { 'node' => 'id' }, )); print Dumper \%ref;
which yields:
$VAR1 = { 'node' => [ { 'desc' => 'network', 'id' => 'net_1.2.3.0' }, { 'desc' => 'ipaddr', 'id' => 'ip_1.2.3.4' } ] };
The output file, /tmp/testfile.xml, looks like this:
<?xml version="1.0" encoding="utf-8"?> <test> <node id="net_1.2.3.0" desc="network" /> <node id="ip_1.2.3.4" desc="ipaddr" /> </test>
So it properly makes id an attribute of the node, but it does the same for desc. I want desc to be a nested element of the node instead. So I need it to look like this:
<?xml version="1.0" encoding="utf-8"?> <test> <node id="net_1.2.3.0"> <desc>network</desc> </node> <node id="ip_1.2.3.4"> <desc>ipaddr</desc> </node> </test>

Note that there will be keys other than desc that will potentially exist in the real hash, and those should be nested elements of the node, too.

Can anyone spot my error(s) or see what XML option I am missing/misusing? Or do I have to reconstruct my hash ref (which is fine, too)?

Btw, I make liberal use of the XML::Simple module elsewhere so I want to stay with that method.

thx!

EDIT

After reading this thread (particularly grantm's post at the end), I got my code to do what I wanted by defining the desc (and other) key values as anonymous arrays:

# create 1st node push(@{$ref{'node'}},{ 'id' => 'net_1.2.3.0', 'desc' => ['network'], 'data' => ['testdata'], }); # create 2nd node push(@{$ref{'node'}},{ 'id' => 'ip_1.2.3.4', 'desc' => ['ipaddr'], 'data' => ['testdata2'], });
Is this the right way to do this? I know, timtowtdi...

In reply to XMLout and Elements vs Attributes by atreyu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.