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

标签 regex xml perl xml-parsing centos

我从 Perl 开始,用这门语言做所有你能做的坏事。该程序使用 XML::Simple 和正则表达式,互联网上说除非你讨厌自己,否则不要这样做。

好的,计划是从网站读取 XML 文件并读取需要更新的 CentOS 6.6 软件包。对于那些不熟悉 CentOS 或 Steve Meier 勘误表 XML 的人,它并没有很好地与 CEBA 编号排列在一起,如下所示...

解析后示例

<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 文件的根元素发生了变化。所以我不得不使用正则表达式来“读取”文件。但是当我使用我的程序时,它不会打印出结果。问题可能与使用的正则表达式或元素搜索的编写方式有关。我不是 100% 确定问题出在哪里,感谢您提供任何帮助。

程序
# 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";
     }
}

最佳答案

您在 foreach 中所做的事情没有 Perl,您在 if 中缺少一些标点符号.像这样的东西应该工作:

#!/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";
    # }
}

也就是说,即使 the XML::Simple documentation说不要用。当 CEBA 条目只有一个 package 时,您可能会遇到问题。标记在里面。

关于regex - 如何使用 Perl 从 XML 中的多个根元素打印结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30793645/

相关文章:

xml - NSXMLParser 跳过具有 namespace 的元素

xml - 如何从XPATH检索名称

perl - 如何优雅地从 Perl 的字符串中拆分成对的单词?

perl - Perl中套接字编程中的问题

java - 匹配特殊字符前的字符串

javascript - jQuery 正则表达式 - 无法将 img 标签的标题属性中的换行/换行替换为 <br>

javascript - 进一步修改密码的正则表达式

xml - 使用 XSLT 1.0 根据 ID 值替换 xml 文件的属性值

perl - 如何使用 Perl 的 Remote::Selenium::WebElement 来验证超链接将带我前往的 URL?

mysql - 正则表达式在 Mysql 中使用分隔符进行搜索