首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Perl从XML中的多个根元素打印结果

问如何使用Perl从XML中的多个根元素打印结果
EN

Stack Overflow用户
提问于 2015-06-12 00:39:59
回答 1查看 183关注 0票数 0

我从Perl开始,用该语言做所有可能的坏事。这个程序使用的是XML::简单的正则表达式,互联网说,除非你讨厌自己,否则不要这么做。

好的,我们的计划是从一个网站读取一个XML文件,并读取需要更新的CentOS 6.6包。对于那些不熟悉CentOS或的人,它与CEBA数字的排列不太好,如下所示.

解析后的示例

代码语言:javascript
复制
<opt>
    <CEBA-2005--169 description="Not available" from="centos-announce@centos.org" issue_date="2005-04-07 01:27:35" notes="Not available" product="CentOS Linux" references="http://rhn.redhat.com/errata/RHBA-2005-169.html http://lists.centos.org/pipermail/centos-announce/2005-April/011555.html" release="1" solution="Not available" synopsis="CentOS and up2date - bugfix update" topic="Not available" type="Bug Fix Advisory">
        <os_arch>i386</os_arch>
        <os_arch>x86_64</os_arch>
        <os_release>4</os_release>
        <packages>up2date-4.4.5.6-2.centos4.i386.rpm</packages>
        <packages>up2date-4.4.5.6-2.centos4.src.rpm</packages>
    </CEBA-2005--169>
    <CEBA-2005--842 description="Not available" from="centos-announce@centos.org" issue_date="2005-11-18 17:52:49" multirelease="1" notes="Not available" product="CentOS Linux" references="https://rhn.redhat.com/errata/RHBA-2005-842.html http://lists.centos.org/pipermail/centos-announce/2005-November/012437.html http://lists.centos.org/pipermail/centos-announce/2005-November/012438.html" release="2" solution="Not available" synopsis="Important CentOS shadow-utils - bugfix update" topic="Not available" type="Bug Fix Advisory">
        <os_arch>i386</os_arch>
        <os_arch>x86_64</os_arch>
        <os_release>4</os_release> 
        <packages>shadow-utils-4.0.3-58.RHEL4.i386.rpm</packages>
    </CEBA-2005--842>

如您所见,XML文件的根元素会发生变化。因此,我不得不使用正则表达式来“读取”文件。但是当我使用我的程序时,它不会打印出结果。问题可能在于所使用的正则表达式或元素搜索是如何编写的。我不能百分之百确定问题在哪里,任何帮助都是感激的。

程序

代码语言:javascript
复制
# Script to parse XML file to show updates.

use strict;
use XML::Simple;
use Data::Dumper;
use LWP::Simple;

my $parser = new XML::Simple;

my $url = 'http://cefs.steve-meier.de/errata.latest.xml';
my $content = get $url or die "Unable to get $url \n";
my $list = $parser->XMLin ($content);
my $CEBA = '(CEBA-([\d]+)--([\d]+))';

foreach my $CEBA (@{$list->{/(CEBA-([\d]+)--([\d]+))/}}) {
     if )$CEBS->{os_release eq '6') {
           print $CEBA->{packages} /. "\n";
     }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-12 01:24:37

您在foreach中所做的不是Perl,您在if中缺少了一些标点符号。像这样的事情应该有效:

代码语言:javascript
复制
#!/usr/bin/perl

use warnings;
use 5.010;

use XML::Simple;
use Data::Dumper;
use LWP::Simple;

# "indirect object" notation (new XML::Simple) is frowned upon
my $parser = XML::Simple->new;

# used this for testing so i wouldn't have to download
# the file for every run.
my $content = do { open my $fh, '<', 'errata.latest.xml' or die; undef $/; <$fh> };
# my $url = 'http://cefs.steve-meier.de/errata.latest.xml';
# my $content = get $url or die "Unable to get $url \n";

my $list = $parser->XMLin($content);
# print Dumper($list);

for my $CEBA (keys %$list) {
    # if the key doesn't match what you want
    # and os_release != 6, then skip to the
    # next entry.
    next unless $CEBA =~ /\ACEBA-\d+--\d+\z/
            and $list->{$CEBA}{os_release} == 6;

    say for @{ $list->{$CEBA}{packages} };
    ## ^-- essentially the same as --v
    # for my $pkg (@{ $list->{$CEBA}{packages} }) {
    #     print "$pkg\n";
    # }
}

尽管如此,甚至连XML::简单文档都说不要使用它。当CEBA条目中只有一个package标记时,您可能会遇到问题。

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

https://stackoverflow.com/questions/30793645

复制
相关文章

相似问题

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