help me refactor this, please

G

gabkin

I am using XML::Simple to get some metadata from an XML file, and I
usually access the metadata like this:

$metadata{Label} = $XML->{LabelName};
$metadata{'Copyright Holder'} = $XML->{RightsHolder};
$metadata{'Release Data'} = $XML->{OriginalReleaseDate};
$metadata{'Product ID'} = $XML->{ProductId};
$metadata{'Thumbnail file'} =
$XML->{DigitalFiles}->{CoverFile}->{FileInfo}->{FileName};

etc.
(This XML file really is overkill, and tends to obfuscate the data, but
it works, and its what I've got.)
But for 'Artist', I have an issue, sometimes XML::Simple gives a hash
for 'Artists', and sometimes it gives a list, with a separate hash
inside the list for each artist. This seems to occur when multiple
artists collaborate on a track/album.
Perhaps my code will illustrate what Im trying to achieve...

# there may be multiple artists, if there are,
# there is a list in 'Artist', followed by a hash:
# otherwise there is just a hash in artist.
# the eval trick will detect whether there is a list there or not,
# and then act accordingly
eval{my $foo = $XML->{Artists}->{Artist}->[0]};
if ($@){ # this will trigger if the above 'look for a list' code bombs
$metadata{Artist} = $XML->{Artists}->{Artist}->{FullName};
} else { # this means there must be multiple artists
my $comboArtistName;
my $Artists = $XML->{Artists}->{Artist};
my $size = @$Artists;
for(my $i=0;$i<$size;$i++){
$comboArtistName.=" & " if $comboArtistName;

$comboArtistName.=$XML->{Artists}->{Artist}->[$i]->{FullName};
}
$metadata{Artist}=$comboArtistName;
} # there must be a better way to do the above

Anyway, I have tested this, and it works, but it seems rather ungainly.
I cant think of another better way of doing this, but I was hoping that
someone else here could...
 
I

it_says_BALLS_on_your_forehead

gabkin said:
I am using XML::Simple to get some metadata from an XML file, and I
usually access the metadata like this:

$metadata{Label} = $XML->{LabelName};
$metadata{'Copyright Holder'} = $XML->{RightsHolder};
$metadata{'Release Data'} = $XML->{OriginalReleaseDate};
$metadata{'Product ID'} = $XML->{ProductId};
$metadata{'Thumbnail file'} =
$XML->{DigitalFiles}->{CoverFile}->{FileInfo}->{FileName};

etc.
(This XML file really is overkill, and tends to obfuscate the data, but
it works, and its what I've got.)
But for 'Artist', I have an issue, sometimes XML::Simple gives a hash
for 'Artists', and sometimes it gives a list, with a separate hash
inside the list for each artist. This seems to occur when multiple
artists collaborate on a track/album.
Perhaps my code will illustrate what Im trying to achieve...

# there may be multiple artists, if there are,
# there is a list in 'Artist', followed by a hash:
# otherwise there is just a hash in artist.
# the eval trick will detect whether there is a list there or not,
# and then act accordingly
eval{my $foo = $XML->{Artists}->{Artist}->[0]};
if ($@){ # this will trigger if the above 'look for a list' code bombs
$metadata{Artist} = $XML->{Artists}->{Artist}->{FullName};
} else { # this means there must be multiple artists
my $comboArtistName;
my $Artists = $XML->{Artists}->{Artist};
my $size = @$Artists;
for(my $i=0;$i<$size;$i++){
$comboArtistName.=" & " if $comboArtistName;

$comboArtistName.=$XML->{Artists}->{Artist}->[$i]->{FullName};
}
$metadata{Artist}=$comboArtistName;
} # there must be a better way to do the above

Anyway, I have tested this, and it works, but it seems rather ungainly.
I cant think of another better way of doing this, but I was hoping that
someone else here could...

it would be much easier if you showed us the output from Dumper.
 
C

Ch Lamprecht

gabkin said:
I am using XML::Simple to get some metadata from an XML file, and I
usually access the metadata like this:

(This XML file really is overkill, and tends to obfuscate the data, but
it works, and its what I've got.)
But for 'Artist', I have an issue, sometimes XML::Simple gives a hash
for 'Artists', and sometimes it gives a list, with a separate hash
inside the list for each artist. This seems to occur when multiple
artists collaborate on a track/album.
Perhaps my code will illustrate what Im trying to achieve...

# there may be multiple artists, if there are,
# there is a list in 'Artist', followed by a hash:
# otherwise there is just a hash in artist.
# the eval trick will detect whether there is a list there or not,
# and then act accordingly
#eval{my $foo = $XML->{Artists}->{Artist}->[0]};
#if ($@){ # this will trigger if the above 'look for a list' code bombs

if (ref ($XML->{Artists}->{Artist})eq 'HASH'){
$metadata{Artist} = $XML->{Artists}->{Artist}->{FullName};
} else { # this means there must be multiple artists
my $comboArtistName;
my $Artists = $XML->{Artists}->{Artist};
my $size = @$Artists;
for(my $i=0;$i<$size;$i++){
$comboArtistName.=" & " if $comboArtistName;

$comboArtistName.=$XML->{Artists}->{Artist}->[$i]->{FullName};
}
$metadata{Artist}=$comboArtistName;
} # there must be a better way to do the above

Anyway, I have tested this, and it works, but it seems rather ungainly.
I cant think of another better way of doing this, but I was hoping that
someone else here could...

Hi,

maybe perldoc -f ref will be helpful?

Christoph
 
J

jl_post

gabkin said:
I am using XML::Simple to get some metadata from an XML file, and I
usually access the metadata like this:

$metadata{Label} = $XML->{LabelName};
$metadata{'Copyright Holder'} = $XML->{RightsHolder}; ...
But for 'Artist', I have an issue, sometimes XML::Simple gives a hash
for 'Artists', and sometimes it gives a list, with a separate hash
inside the list for each artist. This seems to occur when multiple
artists collaborate on a track/album.


Dear gabkin,

What options are you using to open the input XML file? The reason I
am asking is because, depending on the options, the returned object can
look different.

I normally don't want my XML data to be "folded," so I usually just
open XML input files with the following line of code:

my $input = XMLin("one.xml", forcearray => 1,
keeproot => 1,
keyattr => []);

You might want to try this line of code and see if it makes your
$XML input object more consistent.

Whether or not this is the answer you're looking for, I hope you
figure out your problem.

Have a good week!

-- Jean-Luc
 
P

Peter J. Holzer

gabkin said:
But for 'Artist', I have an issue, sometimes XML::Simple gives a hash
for 'Artists', and sometimes it gives a list, with a separate hash
inside the list for each artist. This seems to occur when multiple
artists collaborate on a track/album.
[...]
I normally don't want my XML data to be "folded," so I usually just
open XML input files with the following line of code:

my $input = XMLin("one.xml", forcearray => 1,
keeproot => 1,
keyattr => []);

You might want to try this line of code and see if it makes your
$XML input object more consistent.

forcearray can also be used for particular elements instead of globally.
That way the OP has to change less code.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,183
Messages
2,570,968
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top