如何使用perl解析带有命名空间的redhat alert xml文件

时间:2013-11-28 10:28:38

标签: xml perl xml-namespaces

我使用perl来解析Redhat顾问文件。文件使用命名空间。我想出了如何定义命名空间并提取事物。但是,当我有两级深度的命名空间时,我无法提取信息。例如,我无法打印CVE值, 这是xml文件和我的代码。

<?xml version="1.0" encoding="utf-8"?>
<cvrfdoc xmlns="http://www.icasi.org/CVRF/schema/cvrf/1.1" > 
<Vulnerability Ordinal="1" xmlns="http://www.icasi.org/CVRF/schema/vuln/1.1">
<CVE>CVE-2013-4162</CVE>
</Vulnerability>
<Vulnerability Ordinal="2" xmlns="http://www.icasi.org/CVRF/schema/vuln/1.1">
<CVE>CVE-2013-4299</CVE>
</Vulnerability>

#!/usr/bin/perl -w
use XML::LibXML;
use XML::LibXML::XPathContext;
use Data::Dumper;
     $file="/var/tmp/redhatAdvisories/xyz.xml";                                                                               

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file("$file");
my $xc = XML::LibXML::XPathContext->new($doc);
$xc->registerNs('NSP', 'http://www.icasi.org/CVRF/schema/cvrf/1.1');
$xc->registerNs('NSPV', 'http://www.icasi.org/CVRF/schema/vuln/1.1');
my $cve ="";
my $releaseDate ="";
for my $vul ( $xc->findnodes('//NSP:cvrfdoc/NSPV:Vulnerability') ) {
 my $ord         = $vul->findvalue('@Ordinal');
 $cve=$vul->findnodes('CVE');
 print " Vul Ordinal: $ord,$cve\n";
}

2 个答案:

答案 0 :(得分:2)

你走在正确的轨道上。

首先;继续使用$xc查找节点。请勿致电$vul->findnodes

二;请注意,<CVE>元素命名空间!

for my $vul ( $xc->findnodes('//NSP:cvrfdoc/NSPV:Vulnerability') ) {
    my $ord = $xc->findvalue('@Ordinal', $vul);
    $cve=$xc->findnodes('NSPV:CVE', $vul);
    print " Vul Ordinal: $ord,$cve\n";
}

答案 1 :(得分:0)

我可以提供替代建议吗?只需忽略名称空间,并使用XML::Twig解析它:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> parsefile ( 'your_file.xml' );
foreach my $vuln ( $twig -> findnodes ( '//Vulnerability' ) )
{
    print $vuln -> att ( 'Ordinal' ), ' => ', $vuln -> first_child_text('CVE'),"\n";
}