Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

XML::Generator loop

by hallikpapa (Scribe)
on Mar 30, 2008 at 23:14 UTC ( [id://677416]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to generate xml data that will be read by some flash applications and it has to be in a specific format. Here is a sample of what the output should look like.
<chart caption='Monthly Sales Summary' subcaption='For the year 2006' +xAxisName='Month' yAxisName='Sales' numberPrefix='$'> <set label='January' value='17400' /> <set label='February' value='19800' /> <set label='March' value='21800' /> <set label='April' value='23800' /> <set label='May' value='29600' /> <set label='June' value='27600' /> <set label='July' value='31800' /> <set label='August' value='39700' /> <set label='September' value='37800' /> <set label='October' value='21900' /> <set label='November' value='32900' /> <set label='December' value='39800' /> </chart>
I have been able to successfully get some XML generated. For instance I can do the first line properly, but the problem comes with the loop. It's either I cannot get the syntax right, or it prints the output incorrectly.
my %xml_hash; print $xml->chart({caption => 'Chart Title', subcaption => 'Subtit +le', xAxisName => 'xAxis', yAxisName => 'yAxis'}); while ( my $row = $sp->fetchrow_hashref ) { push @{ $xml_hash{set} }, $row; } my $xmlOut = XMLout(\%xml_hash, NoAttr => 1, RootName => 'chart'); print $xmlOut;
If run this code, it prints output like this
<chart caption="Chart Title" xAxisName="xAxis" yAxisName="yAxis" subcaption="Subtitle" /><chart> <set> <label>January</label> <value>10622</value> </set> .. ... </chart>
If I try and put a foreach loop inside the creation of the XML, it gives me syntax errors
print $xml->chart({caption => 'Chart Title', subcaption => 'Subtitle', + xAxisName => 'xAxis', yAxisName => 'yAxis'}, foreach my $key ( sort keys %hash) { my ( $date, $cust ) = split( /:/, $key ); $xml->data({set => },['set'], $hash{$key}[2]); });
Any ideas on how to proceed? Thanks!

Replies are listed 'Best First'.
Re: XML::Generator loop
by GrandFather (Saint) on Mar 31, 2008 at 00:41 UTC

    XML::Simple is not simple! In this case it may be better to hand roll the inner block of XML that is causing you grief. Something based on the following perhaps?

    use warnings; use strict; my @rows = ( {label=>'January', value=>'17400'}, #... {label=>'December', value=>'39800'}, ); print "<set label='$_->{label}' value='$_->{value}' />\n" for @rows;

    Prints:

    <set label='January' value='17400' /> <set label='December' value='39800' />

    If you need entity handling or other XML generation help then you would be better to use one of the modules designed for generating XML such as XML::Writer.


    Perl is environmentally friendly - it saves trees
Re: XML::Generator loop
by pc88mxer (Vicar) on Mar 31, 2008 at 00:46 UTC
    There may be another way to do this, but when using XML::Generator it appears you have to build the XML from the inside out (or 'bottom up') like this:
    use XML::Generator; my $xml = new XML::Generator; my @list; while (<DATA>) { chomp; my ($m, $d) = split(' ', $_); push(@list, $xml->set( { label => $m, value => $d })); } print $xml->chart({ caption => 'Chart Title', subcaption => 'Subtitle' + }, @list); __END__ January 17400 February 19800 March 21800 April 23800 May 29600 June 27600 July 31800 August 39700 September 37800 October 21900 November 32900 December 39800
    Also, I'm not sure why you are mixing XML::Simple (i.e. XMLout) and XML::Generator. I would use just one or the other.
Re: XML::Generator loop
by Cody Pendant (Prior) on Mar 31, 2008 at 02:51 UTC
    Surely the reason you've got no attributes is because you've use the "NoAttr" option?

    From the POD: "When used with XMLout(), the generated XML will contain no attributes. All hash key/values will be represented as nested elements instead."



    Nobody says perl looks like line-noise any more
    kids today don't know what line-noise IS ...
Re: XML::Generator loop
by Jenda (Abbot) on Mar 31, 2008 at 17:45 UTC
    use strict; use XML::Rules; my $parser =XML::Rules->new(rules =>[]); my @list; while (<DATA>) { chomp; my ($m, $d) = split(' ', $_); push(@list, { label => $m, value => $d }); } print $parser->ToXML( chart => { caption => 'Monthly Sales Summary', subcaption => 'For the year 2006', xAxisName => 'Month', yAxisName => 'Sales', numberPrefix => '$', set => \@list, }, 0, ' ' ) __END__ January 17400 February 19800 March 21800 April 23800 May 29600 June 27600 July 31800 August 39700 September 37800 October 21900 November 32900 December 39800

    The XML::Rules->ToXML() converts (or tries to convert) a datastructure to XML using attributes whenever possible and subtags in other cases. In this case the hash of data for <chart> contain set => \@array,, since attributes cannot be repeated, the set must be a subtag and be repeated. The last two parameters to ->ToXML are there just to add the formatting.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://677416]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-19 15:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found