首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迭代散列的Perl散列和散列数组

迭代散列的Perl散列和散列数组
EN

Stack Overflow用户
提问于 2012-08-07 03:23:23
回答 2查看 270关注 0票数 0

我又被困住了,需要一些帮助。像往常一样,这是我的死对头-哈希。本质上,我正在尝试写入一个数据库,即z/OS大型机上的所有软件项。我已经成功地进行了以下散列:

代码语言:javascript
复制
$VAR1 = {
    'Product' => {
        'Unicenter CA-Deliver Output Management' => {
            'vendorUniqueKeyRef' => 'CA',
            'swUniqueKey'        => 'RMO',
            'description'        => 'Unicenter CA-Deliver Output Management'
        },
        'Unicenter CA-JCLCheck Utility' => {
            'vendorUniqueKeyRef' => 'CA',
            'swUniqueKey'        => 'JCLCHECK',
            'description'        => 'Unicenter CA-JCLCheck Utility'
        },
        'EREP Environmental Recording Edit Print' => {
            'vendorUniqueKeyRef' => 'IBM',
            'swUniqueKey'        => 'EREP',
            'ProductVersion'     => {
                'version'       => '3',
                'swUniqueKey'   => '5658-260',
                'name'          => 'EREP Environmental Recording Edit Print',
                'versionNumber' => '03'
            },
            'description' => 'EREP Environmental Recording Edit Print'
        },
        'SYSQL' => {
            'vendorUniqueKeyRef' => 'SPLWDGRP',
            'swUniqueKey'        => 'SYSQL',
            'ProductVersion'     => {
                'ProductVersionRelease' => {
                    'releaseNumber' => '01',
                    'swUniqueKey'   => 'SYSQL-21',
                    'name'          => 'SYSQL',
                    'release'       => '1'
                },
                'version'       => '2',
                'swUniqueKey'   => 'SYSQL-2',
                'name'          => 'SYSQL',
                'versionNumber' => '02'
            },
            'description' => 'SYSQL'
        },
        '3270-PC File Transfer Program' => {
            'vendorUniqueKeyRef' => 'IBM',
            'swUniqueKey'        => '3270PCFT',
            'description'        => '3270-PC File Transfer Program'
        },
        'Tivoli OMEGAMON XE on z/OS' => {
            'vendorUniqueKeyRef' => 'IBM',
            'swUniqueKey'        => 'OMXEZO',
            'ProductVersion'     => {
                'version'       => '3',
                'swUniqueKey'   => '5698-A59',
                'name'          => 'Tivoli OMEGAMON XE on z/OS',
                'versionNumber' => '03'
            },
            'description' => 'Tivoli OMEGAMON XE on z/OS'
        },
        'Tivoli OMEGAMON XE for Messaging for z/OS' => {
            'vendorUniqueKeyRef' => 'IBM',
            'swUniqueKey'        => 'OMXEMES',
            'description'        => 'Tivoli OMEGAMON XE for Messaging for z/OS'
        },
        'DB2 Utilities Suite for z/OS' => {
            'vendorUniqueKeyRef' => 'IBM',
            'swUniqueKey'        => 'DB2UTSU',
            'ProductVersion'     => {
                'DB2 Utilities Suite for z/OS' => {
                    'swUniqueKey'   => '5655-N97',
                    'version'       => '9',
                    'versionNumber' => '09'
                },
                'DB2 Utilities Suite' => {
                    'swUniqueKey'   => '5697-E98',
                    'version'       => '7',
                    'versionNumber' => '07'
                }
            },
            'description' => 'DB2 Utilities Suite for z/OS'
        },
        'UMB' => {
            'vendorUniqueKeyRef' => 'CSC',
            'swUniqueKey'        => 'CSCUMB',
            'description'        => 'UMB'
        }
    }
};

最初,一切都很好,我有以下几点:

代码语言:javascript
复制
my $sw = $xmldoc->{'Catalog'}->{'Products'};
my %sw = %{ $sw->{'Product'} };

foreach my $product (keys %sw) {
    print "Now processing $product\n";
    my $version;
    my $release;
    my $description        = $sw{$product}{'description'};
    my $vendorUniqueKeyRef = $sw{$product}{'vendorUniqueKeyRef'};
    my $swUniqueKey        = $sw{$product}{'swUniqueKey'};
    if ($sw{$product}{'ProductVersion'}) {
        $version = $sw{$product}{'ProductVersion'}{'version'};
        if ($sw{$product}{'ProductVersion'}{'ProductVersionRelease'}) {
            $release =
                $sw{$product}{'ProductVersion'}{'ProductVersionRelease'}
                {'release'};
        }
        else {
            $release = 0;
        }
    }
    else {
        $version = 0;
        $release = 0;
    }

    my $fullVersion = "$version.$release";

    print "        ***************\n
    The product is: $product\n
    The description is: $description\n
    The vendorUniqueKeyRef is: $vendorUniqueKeyRef\n
    The ProductVersion is: $fullVersion\n
    The swUniqueKey is: $swUniqueKey\n
    ***************\n";
}

但是,在使用strict时,我一直收到关于使用未初始化变量的错误。我意识到一些软件有像".2“这样的版本,而不是"2.2”,然后我发现我没有正确处理一些产品被安装了两次不同版本的事实,这是我愚蠢地没有迎合的。

我试图解决这个问题,结果发现并不是所有的版本都有发行版,这是我试图迎合的,但前提是它们只安装了一次......

我已经阅读了大量关于从HoH和AoH中获取数据的内容,但我不能正确地理解这一点。

本质上,我试图使用DBD::ODBC (我已经在我的程序的其余部分中使用它)获得从这个散列中安装到数据库中的所有软件的列表,无论它有一个版本,多个版本,版本和发行,多个版本和没有发布,多个版本......好吧,你明白了……

我非常感谢任何人对我目前的风格和错误检查提供的任何建议。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-07 05:58:58

我想你在用XML::Simple?如果是这样的话,最好使用像XML::LibXMLXML::Twig这样的类似于XPath的数据解析器。

现在,您最好维护标量变量,使其指向散列结构中的每一步。这将避免多个键访问一个元素,以及重复使用相同的散列访问。您不应该像在my %sw = %{ $sw->{'Product'} }中那样复制到另一个散列,因为复制所有散列键和值是没有意义的。我在下面的代码中使用了my $products = $sw->{Product},然后使用了my $product = $products->{$prodname}my $pv = $product->{ProductVersion}

您还可以从使用散列切片中获益,并且如果您在散列关键字周围删除引号,代码应该会更清晰(只有在关键字是字母数字的情况下才有效)。我使用切片在一行中提取前三个产品参数。

这是您向我们展示的代码的重写。最大的变化是我检查了是否有ProductVersion/version元素。如果是这样,那么我将从ProductVersion下面组合versionProductVersionRelease/release。否则,我将在所有ProductVersion/*元素下执行相同的操作。如果这些值不存在,则定义的// -or可用于将这些值默认为零。

我希望这更接近你想要的。

代码语言:javascript
复制
my $products = $sw->{Product};

foreach my $prodname (keys %$products) {

    print "\n\nNow processing $prodname\n";

    my $product = $products->{$prodname};

    my ($description, $vendorUniqueKeyRef, $swUniqueKey) =
            @$product{qw/ description vendorUniqueKeyRef swUniqueKey /};

    my @versions;
    if (my $pv = $product->{ProductVersion}) {
        for my $ver (exists $pv->{version} ? $pv : values %$pv) {
          push @versions, sprintf "%d.%d",
              $ver->{version} // 0,
              $ver->{ProductVersionRelease}{release} // 0;
        }
    } 

    print "***************\n";
    print "The product is: $prodname\n";
    print "The description is: $description\n";
    print "The vendorUniqueKeyRef is: $vendorUniqueKeyRef\n";
    print "The ProductVersion is: $_\n" for @versions;
    print "The swUniqueKey is: $swUniqueKey\n";
    print "***************\n";
}

输出

代码语言:javascript
复制
Now processing DB2 Utilities Suite for z/OS
***************
The product is: DB2 Utilities Suite for z/OS
The description is: DB2 Utilities Suite for z/OS
The vendorUniqueKeyRef is: IBM
The ProductVersion is: 9.0
The ProductVersion is: 7.0
The swUniqueKey is: DB2UTSU
***************

Now processing UMB
***************
The product is: UMB
The description is: UMB
The vendorUniqueKeyRef is: CSC
The swUniqueKey is: CSCUMB
***************

Now processing EREP Environmental Recording Edit Print
***************
The product is: EREP Environmental Recording Edit Print
The description is: EREP Environmental Recording Edit Print
The vendorUniqueKeyRef is: IBM
The ProductVersion is: 3.0
The swUniqueKey is: EREP
***************

Now processing Unicenter CA-JCLCheck Utility
***************
The product is: Unicenter CA-JCLCheck Utility
The description is: Unicenter CA-JCLCheck Utility
The vendorUniqueKeyRef is: CA
The swUniqueKey is: JCLCHECK
***************

Now processing Unicenter CA-Deliver Output Management
***************
The product is: Unicenter CA-Deliver Output Management
The description is: Unicenter CA-Deliver Output Management
The vendorUniqueKeyRef is: CA
The swUniqueKey is: RMO
***************

Now processing 3270-PC File Transfer Program
***************
The product is: 3270-PC File Transfer Program
The description is: 3270-PC File Transfer Program
The vendorUniqueKeyRef is: IBM
The swUniqueKey is: 3270PCFT
***************

Now processing SYSQL
***************
The product is: SYSQL
The description is: SYSQL
The vendorUniqueKeyRef is: SPLWDGRP
The ProductVersion is: 2.1
The swUniqueKey is: SYSQL
***************

Now processing Tivoli OMEGAMON XE for Messaging for z/OS
***************
The product is: Tivoli OMEGAMON XE for Messaging for z/OS
The description is: Tivoli OMEGAMON XE for Messaging for z/OS
The vendorUniqueKeyRef is: IBM
The swUniqueKey is: OMXEMES
***************

Now processing Tivoli OMEGAMON XE on z/OS
***************
The product is: Tivoli OMEGAMON XE on z/OS
The description is: Tivoli OMEGAMON XE on z/OS
The vendorUniqueKeyRef is: IBM
The ProductVersion is: 3.0
The swUniqueKey is: OMXEZO
***************
票数 1
EN

Stack Overflow用户

发布于 2012-08-07 04:05:58

看看你的产品DB2 Utilities Suite for z/OS。在ProductVersion密钥中还有另外两个产品名称。其他所有人都没有。

代码语言:javascript
复制
'DB2 Utilities Suite for z/OS' => {
  'vendorUniqueKeyRef' => 'IBM',
  'swUniqueKey' => 'DB2UTSU',
  'ProductVersion' => {
    'DB2 Utilities Suite for z/OS' => {
      'swUniqueKey' => '5655-N97',
      'version' => '9',
      'versionNumber' => '09'
    },
    'DB2 Utilities Suite' => {
      'swUniqueKey' => '5697-E98',
      'version' => '7',
      'versionNumber' => '07'
    }
  },
  'description' => 'DB2 Utilities Suite for z/OS'
},

你需要迎合这一点。您的XML数据有XML模式吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11834554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档