How can I get an XML element's attribute with Perl's XML::Simple?
Solution 1
Well, from the XML you posted, I get this:
Entity: line 3: parser error : Opening and ending tag mismatch: league line 0 and leage
It doesn't even appear to be a strict/warnings issue because it appears when I comment my USUW out.
But if you have the right tags, this should work:
$xml->{game}{name};
And if I call XMLin
with KeepRoot => 1
, you'll find it at:
$xml->{league}{game}{name};
If you are having trouble locating how the data is being read in, do this:
use 5.010;
use strict;
use warnings;
use Data::Dumper;
use XML::Simple;
my $xml = XMLin( $input );
say Data::Dumper->Dump( [ $xml ], [ '$xml' ] );
And then use the path to the structures presented.
Note:
$xml->{league}->{game}->['name'];
should have died with: "Not an ARRAY reference at" even without warnings enabled. ['string']
is a reference to an array with the string 'string'
as the sole element. And, if $xml->{league}{game}
were an array, it would have died with a non-numeric error, because strings don't address arrays.
Solution 2
I normally instantiate my XML::Simple objects like this:
use XML::Simple ':strict';
my $xs = XML::Simple->new( KeepRoot => 1, KeyAttr => 1, ForceArray => 1 );
it allows the structure to be consistent between single and possibly multiple sub-elements. With those settings, this code gets your value:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple ':strict';
my $xs = XML::Simple->new( KeepRoot => 1, KeyAttr => 1, ForceArray => 1 );
my $ref = $xs->XMLin('data.xml');
print $ref->{league}[0]{game}[0]{name};
I added another game tag, and an attribute on the league tag as an example, this is the xml:
<league name="baz">
<game name="bla"/>
<game name="foo"/>
</league>
And the Data::Dumper output is:
$VAR1 = {
'league' => [
{
'game' => [
{
'name' => 'bla'
},
{
'name' => 'foo'
}
],
'name' => 'baz'
}
]
};
Comments
-
baklap almost 2 years
I have a Perl script that reads a XML file that doesn't have content, only attributes in the element.
Like this:
<league> <game name="bla"/> </league>
Now I try to get the game attribute 'name'.
I tried using
$xml->{league}->{game}->{name}
and$xml->{league}->{game}->['name']
but they are both not working. Something about a hash problem.Is there anybody who can help me get the value?
-
baklap over 13 years$xml->{game}{name}; gives me a: Not a HASH reference at parser.pl line 22.
-
Axeman over 13 years@baklap, see the suggestion for
Data::Dumper
. -
baklap over 13 yearsthanks, made it output to a file. But I see what's wrong. The xml I posted was just a a quick example, not the real xml. My bad. The thing that is going wrong is that some are {element} things and some are ['name'] (don't know what the difference is) I'm able to print the {element} things, but the ['name'] things arent printable, I don't know how to do that...
-
Axeman over 13 years@baklap, I don't understand "['name'] things." What options are you passing to XMLin? If it appeared in the dump as
['name']
then it's the same thing as:$array_ref->[0] = 'name'
, if you see square brackets, it's in an array--although I don't understand why it wouldn't have the attribute value ("blah"
in the toy case) near by it. -
Grant McLean over 13 yearsSetting
KeyAttr => 1
doesn't make much sense. Perhaps you meanKeyAttr => {}
. -
Roy van Os over 13 yearsKeyAttr => [], rather, I guess '1' would break on XML tags named '1'