Reputation: 257
I am running through the gentle introduction to XML::LibXML
at Perl XML::LibXML by Example and cannot seem to get hash attributes working. For example, what is wrong with the following code?
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
my $version = XML::LibXML::LIBXML_VERSION;
my $dot_version = XML::LibXML::LIBXML_DOTTED_VERSION;
my $run_version = XML::LibXML::LIBXML_RUNTIME_VERSION;
print "LibXML version: $version\n";
print "LibXML dotted version: $dot_version\n";
print "LibXML runtime version: $run_version\n";
print "Perl version: $^V\n";
my $xml = q{
<record>
<entry atr1="a" atr2="b" atr3="c" />
</record>
};
my $dom = XML::LibXML->load_xml( string => $xml );
my ($entry) = $dom->documentElement->getChildrenByTagName('entry');
print "\$entry is a: ", ref($entry), "\n";
print "node name: ", $entry->nodeName, "\n";
print "Attribute: ", $entry->getAttribute('atr1'), "\n"; # Line 26
print "Attribute: ", $entry->{'atr1'}, "\n"; # Line 27
With the following output:
$./hashtest.pl
LibXML version: 20706
LibXML dotted version: 2.7.6
LibXML runtime version: 20706
Perl version: v5.10.1
$entry is a: XML::LibXML::Element
node name: entry
Attribute: a
Not a HASH reference at ./hashtest.pl line 27.
I am expecting lines 26 and 27 to have the same output. Any guidance would be much appreciated.
Edit: Added more complete version information
Upvotes: 0
Views: 269
Reputation: 7008
As the author of the guide that you have been using, I'm sorry that you've encountered this problem and feel that the tone of some of the comments and replies here has been unduly harsh.
The code you posted does work on versions of XML::LibXML that support it and is covered in the OVERLOADING section of the XML::LibXML::Element docs. This "tied hash" interface is a more 'Perlish' way to access attribute values than calling the getAttribute()
method. One advantage is that the hash access works inside a double-quoted string whereas an explicit method call will not.
From my reading of the ChangeLog, this overloading behaviour was added to the Element class in version 1.91 released on 2012-02-21, although the AttributeHash interface has been available since at least 2009.
I have updated the tutorial section to mention that this function is not available on older versions of XML::LibXML. I did originally consider including that warning, but decided against it since the feature has been in XML::LibXML for so long.
As a general rule, if you're using a Perl object, it would be considered very poor practice to assume the object was a hashref and poke around inside it to access hash values. However that's not what's happening in this case and the hash you're accessing has been provided and documented for exactly that purpose.
If I was going to use a method call to get the value, I'd probably use:
$entry->findvalue('./@atr1')
since this can easily be adapted to access text or attribute content from nested elements as well.
Upvotes: 2
Reputation: 386331
The ability to use
$entry->{'atr1'}
was added to XML::LibXML in version 1.91. It's equivalent to
$entry->getAttributeHash()->{$name}
You must have an older version of XML::LibXML. You could upgrade XML::LibXML, but you might as well use
$entry->getAttribute('atr1')
Upvotes: 2