我有我认为是一个引用哈希数组的哈希。我想要了解的是如何访问这个哈希数组中的哈希元素。
编辑:这是完整的哈希结构
$VAR1 = {
'CVE-2015-0677' => {
'vuln:references' => [
{
'attr' => {
'reference_type' => 'VENDOR_ADVISORY',
'xml:lang' => 'en'
},
'vuln:source' => 'CISCO',
'vuln:reference' => [
{
'attr' => {
'href' => 'http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20150408-asa',
'xml:lang' => 'en'
}
}
]
}
],
'vuln:published-datetime' => '2015-04-12T21:59:03.033-04:00',
'vuln:last-modified-datetime' => '2015-04-13T17:45:18.310-04:00',
'vuln:vulnerable-software-list' => [
'cpe:/o:cisco:adaptive_security_appliance_software:9.0.3',
'cpe:/o:cisco:adaptive_security_appliance_software:8.4.5',
],
'vuln:summary' => 'The XML parser in Cisco Adaptive Security Appliance (ASA) Software 8.4 before 8.4(7.28), 8.6 before 8.6(1.17), 9.0 before 9.0(4.33), 9.1 before 9.1(6), 9.2 before 9.2(3.4), and 9.3 before 9.3(3), when Clientless SSL VPN, AnyConnect SSL VPN, or AnyConnect IKEv2 VPN is used, allows remote attackers to cause a denial of service (VPN outage or device reload) via a crafted XML document, aka Bug ID CSCus95290.'
}
};
如果我尝试以下操作,则第一个Data :: Dumper输出的输出与第二个输出相同。
for my $key ( keys $hash ) {
my @references = $hash->{$key}{'vuln:references'};
print Dumper(@references); #1
for my $vulnref (@references) {
print Dumper($vulnref); #2
}
}
#1
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
#2
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
所以我的for循环似乎没有任何影响?
但是,如果我循环两次,那么第二次循环
for my $key ( keys $hash ) {
my @references = $hash->{$key}{'vuln:references'};
print Dumper(@references); #1
for my $vulnref (@references) {
for my $vuln ($vulnref) {
print Dumper($vuln); #2
}
}
}
#1
$VAR1 = [
{
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
}
];
#2
$VAR1 = {
'vuln:reference' => 'VENDOR',
'vuln:source' => 'CISCO',
};
我现在似乎正在访问哈希。
我相信我在这里缺少一些基本的东西。
非常感谢。
答案 0 :(得分:1)
您没有显示散列的最高级别。您显示的$VAR1
是$hash->{key}
的值,但我不知道key
可能是什么。
无论如何,使用我所拥有的,
$hash->{key}
是对哈希的引用,其中包含一个带有键vuln:references
的单个元素
$hash->{key}{'vuln:references'}
是对数组的引用,其中包含索引为零的单个元素
$hash->{key}{'vuln:references'}[0]
是对另一个哈希的引用,这次使用两个元素
你没有说你想对这些数据做什么,但看起来你需要的只是
my $data = $hash->{key}{'vuln:references'}[0];
for my $key (keys %$data) {
printf "%s => %s\n", $key, $data->{$key};
}
<强>输出强>
vuln:source => CISCO
vuln:reference => VENDOR
<强>更新强>
您没有说明如何定义$key
,而是
for my $data ( $hash->{$key}{'vuln:references'} ) { ... }
你写了一个循环,执行一次,$data
设置为我上面描述的数组引用。
要遍历整个结构,假设$hash
引用的最外面的哈希值和内部数组是唯一具有多个元素的图层,您可以编写
for my $cve ( keys %$hash ) {
my $refs = $hash->{$cve}{'vuln:references'};
print $cve, " \n";
for my $ref ( @$refs ) {
printf " %s => %s\n", $_, $ref->{$_} for keys %$ref;
print "\n";
}
}
请注意keys %$hash
,@$refs
和%$ref
中结构的解除引用。在更新版本的Perl中,您可以使用keys $hash
而无需取消引用,但它是一项实验性功能,不应在实时代码中使用,如果您已use warnings
,则会生成警告消息你应该(和use strict
一起)在你的程序顶部
至于为什么你的代码转储相同的值两次,你有
my @references = $hash->{$key}{'vuln:references'};
将数组@references
设置为保存一个元素,这是该点哈希的数组引用。然后
print Dumper(@references);
逐个转储数组的每个元素。因为只有一个元素,所以它只输出一个转储。最后
for my $vulnref (@references) {
for my $vuln ($vulnref) {
print Dumper($vuln);
}
}
将$vulnref
设置为@references
的每个元素。因为只有一个循环执行一次,$vulnref
设置为数组引用。然后$vuln
设置为列表( $vulnref )
的每个元素,因此它需要同一参考的另一个副本。最后转储该值,结果显示与之前相同的数组引用。
请记住,Perl标量值以$
开头;即使数组的元素是$array[0]
,它也被视为单值,即使该值是引用。如果您想访问它引用的数据,您必须使用适当的符号取消引用它