(Regarding the article (also posted to the author with a little different wording).)
The code for the pet shop could be further shortened by using ForceArray => [dog, cat, hippo]. Not only would this make the structure returned by XMLin simpler, but it'd save the developer from having to unwrap the one item arrays. And would save some memory.

In case anyone is interested this is the implementation of the task (except for the ordering) using XML::Rules:

#!/usr/bin/perl -w use strict; use XML::Rules; use Date::Calc qw(Add_Delta_YM Decode_Date_EU Delta_Days Delta_YMD); u +se Data::Dumper; my @now = (localtime(time))[5, 4, 3]; $now[0] += 1900; # Perl years start in 1900 $now[1]++; # months are zero-based my $parser = XML::Rules->new( rules => [ price => sub { price => fixPrice( $_[1]->{_content}, 0.20 )}, dob => sub {age => dob2age( $_[1]->{_content})}, 'name,owner' => 'content', 'dog,cat,hippo' => sub {delete($_[1]->{_content}); $_[0] => $_[1]}, + ], style => 'filter', ); $parser->filterfile('pets.xml', \*STDOUT); # ... and the functions defined in the article
It's 67 lines and unlike the XML::Simple implementation works as a filter ... only the data of a single animal are in memory at any time.

With the ordering it's

#!/usr/bin/perl -w use strict; use XML::Rules; use Date::Calc qw(Add_Delta_YM Decode_Date_EU Delta_Days Delta_YMD); u +se Data::Dumper; my @now = (localtime(time))[5, 4, 3]; $now[0] += 1900; # Perl years start in 1900 $now[1]++; # months are zero-based my $parser = XML::Rules->new( rules => [ price => sub { price => fixPrice( $_[1]->{_content}, 0.20 )}, dob => sub {age => dob2age( $_[1]->{_content})}, 'name,owner' => 'content', '_default' => 'no content array', 'pets' => sub { my ($tag, $attrs) = @_; delete($attrs->{_content}); foreach my $kind (values %{$attrs}) { next unless ref($kind) eq 'ARRAY'; # just in case $kind = [sort {$a->{name} cmp $b->{name}} @$kind]; # sort the animals of a kind by name }; return $tag => $attrs; }, ], style => 'filter', ident => ' ', ); $parser->filterfile('pets.xml', \*STDOUT); # ... and the functions (78 lines in total)
though this of course can't work as a filter since it has to be able to sort everything. Whether that's clearer than the XML::Simple based code is a question :-)

P.S.: You need XML::Rules 0.17 for the identation to work.


In reply to Re: XML plus Perl -- simply magic by Jenda
in thread XML plus Perl -- simply magic by marto

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.