我正在XML::LibXML
处对Perl XML::LibXML by Example的温和介绍,似乎无法使哈希属性正常工作。例如,以下代码有什么问题?
#!/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
使用以下输出:
$./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.
我希望第26行和第27行具有相同的输出。任何指导都将非常感谢。
修改:添加了更多完整版本信息
答案 0 :(得分:2)
作为您一直使用的指南的作者,我很抱歉您遇到了这个问题,并且觉得这里的一些评论和回复的语气过于刺耳。
您发布的的代码适用于支持它的XML :: LibXML版本,OVERLOADING section of the XML::LibXML::Element docs中涵盖 。与调用getAttribute()
方法相比,这种“绑定哈希”接口是访问属性值的更“Perlish”方式。一个优点是散列访问在双引号字符串内部工作,而显式方法调用则不起作用。
从我对ChangeLog的阅读中,这个重载行为被添加到2012-02-21发布的版本1.91中的Element类中,尽管AttributeHash接口至少从2009年开始提供。
我更新了tutorial section,提到旧版本的XML :: LibXML上没有此功能。我最初考虑包含该警告,但是由于该功能已经在XML :: LibXML中存在了很长时间,所以我决定反对它。
作为一般规则,如果您正在使用Perl对象,那么假设该对象是一个hashref并在其内部进行访问以访问哈希值将被视为非常糟糕的做法。然而,这并不是在这种情况下发生的情况,并且您正在访问的哈希已经提供并记录在那个目的。
如果我打算使用方法调用来获取值,我可能会使用:
$entry->findvalue('./@atr1')
因为这可以很容易地适应从嵌套元素访问文本或属性内容。
答案 1 :(得分:2)
使用
的能力$entry->{'atr1'}
在版本1.91中添加到XML :: LibXML中。它相当于
$entry->getAttributeHash()->{$name}
您必须拥有旧版本的XML :: LibXML。您可以升级XML :: LibXML,但您也可以使用
$entry->getAttribute('atr1')