0

我又被困住了,需要一些帮助。像往常一样,这是我的克星——哈希。本质上,我正在尝试将 z/OS 大型机上的所有软件项目写入数据库。我已经设法发展到以下哈希:

$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'
        }
    }
};

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

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";
}

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

我试图解决这个问题,却发现并非所有版本都有一个版本,我试图迎合这个问题,但前提是它们已经安装了一次......

我已经阅读了从 HoH 和 AoH 中获取数据的负载,但我不能正确地解决这个问题。

本质上,我正在尝试使用 DBD::ODBC(我已经为我的程序的其余部分工作)从这个散列中安装的所有软件的列表,无论它有一个版本、多个版本、版本和发布,多个版本,没有发布,多个版本……嗯,你明白了……

我将不胜感激任何人提供的任何帮助,以及对我当前风格和错误检查的任何建议。

提前致谢。

4

2 回答 2

1

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

'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 模式吗?

于 2012-08-06T20:05:58.173 回答
1

我想你正在使用XML::Simple?如果是这样,您最好使用 XML 解析器,它可以让您以类似 XPath 的方式访问您的数据,例如XML::LibXMLXML::Twig.

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

您还可以通过使用散列切片受益,如果您从散列键周围去掉引号(这仅在键是字母数字时有效),代码会更清晰。我使用切片在一行中提取前三个产品参数。

这是您向我们展示的一段代码的重写。最大的变化是我检查了是否有ProductVersion/version元素。如果是这样,那么我结合versionProductVersionRelease/release从下方ProductVersion。否则我在所有 ProductVersion/*元素下做同样的事情。如果这些//值不存在,defined-or 可用于将这些值默认为零。

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

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";
}

输出

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
***************
于 2012-08-06T21:58:58.057 回答