xml - 无法使用 perl 从 XML 文件中获取值
问题描述
下面是xml文件:
<Build_details>
<Release number="1902">
<Build number="220">
<OMS>
<Build_path>ST_OMS_V19021_B220</Build_path>
<Pc_version>8042.18.01</Pc_version>
</OMS>
<OMNI>
<Build_path>ST_OMNI_V19021_B220</Build_path>
</OMNI>
</Build>
</Release>
<Release number="1810">
<Build number="340">
<OMS>
<Build_path>ST_OMS_V1810_B340</Build_path>
<Pc_version>8041.30.01</Pc_version>
</OMS>
<OMNI>
<Build_path>ST_OMNI_V1810_B340</Build_path>
</OMNI>
</Build>
</Release>
<Release number="1810">
<Build number="300">
<OMS>
<Build_path>ST_OMS_V18102_B300</Build_path>
<Pc_version>8041.30.01</Pc_version>
</OMS>
<OMNI>
<Build_path>ST_OMNI_V18102_B300</Build_path>
</OMNI>
</Build>
</Release>
</Build_details>
我无法获取具有其他版本号的相同版本号的值。假设我想获取版本 1810 build 300 的详细信息,它会抛出空值。似乎我编写的 perl 脚本仅适用于第一次出现的值。
下面是我写的脚本:
#!/appl/OMS/perl/bin/perl
=comments
Perl wrapper for parsing the central repository
xml to fetch relevant data of each release
Help Usage : ./parseenv.pl allrel -- to list all versions\
./parseenv.pl <relno> <buildno> <oms/pc/omni>
ex - ./parseenv.pl 1810 300 oms
Date=20180910
=cut
use XML::Smart;
use File::Path qw(make_path remove_tree);
$FILE="/appl/OMS/Build_Details/build_details.xml";
$xml = XML::Smart->new($FILE) || die ("Could not open XML file");
my $relno=$ARGV[0];
my $build=$ARGV[1];
if ( $ARGV[0] =~ "allrel" ) {
my @release=$xml->{Build_details}->{Release}('[@]','number');
foreach $i (@release) {
print "$i\n";
}
}
if ($ARGV[1] =~ "build") {
my @build=$xml->{Build_details}->{Release}->('number','eq',"$relno")->{Build}('[@]','number');
foreach $i (@build) {
print "$i\n";
}
}
if ($ARGV[2] =~ "oms") {
my @oms=$xml->{Build_details}->{Release}->('number','eq',"$relno")->{Build}('number','eq',"$build")->{OMS}->{Build_path};
print "@oms\n";
}
elsif ($ARGV[2] =~ "pc") {
my @pc=$xml->{Build_details}->{Release}->('number','eq',"$relno")->{Build}('number','eq',"$build")->{OMS}->{Pc_version};
print "@pc\n";
}
elsif ($ARGV[2] =~ "omni") {
my @omni=$xml->{Build_details}->{Release}->('number','eq',"$relno")->{Build}('number','eq',"$build")->{OMNI}->{Build_path};
print "@omni\n";
}
else {
print "Please enter 3rd argument"
}
输出细节:
第一次出现效果很好
$ ./parsebuilddetails.pl 1810 340 pc
8041.30.01
不适用于另一种情况:
$ ./parsebuilddetails.pl 1810 300 pc
如何修改 perl 脚本以使其适用于内部版本号的所有值。看来我将不得不添加一个循环。但我无法理解它将如何迭代。请帮忙 :)
解决方案
始终使用严格和警告的编译指示!只是 XML::LibXML 的示例:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;
my $xml_string = join '', <DATA>;
my $dom = XML::LibXML->load_xml(string => $xml_string);
foreach my $build_node ($dom->findnodes('//Release[@number="1810"]/Build')) {
print $build_node->to_literal;
}
__DATA__
...place your xml here
推荐阅读
- laravel - Laravel 7 未定义的方法
- java - Springboot put 方法不起作用(控制台显示 get 调用)
- python - Python:如何通过仅保留恒定信息来连接两个数据帧?
- probability - 如何表达保护方法的有效性
- jenkins - 使用声明性管道脚本,从文件夹中获取文件名并将其分配给全局变量,并在另一个阶段调用该变量
- ssis - SSIS - 使用源表中的不匹配行更新目标表(使用 Pentaho 数据集成)
- php - 如何使用 RewriteRule 以便为 PHP 修改 $_SERVER['REQUEST_URI']?
- google-cloud-platform - 如何在 Google Cloud Load Balancer 上记录 SSL/TLS 握手详细信息
- ruby-on-rails - 关于关联列的rails验证唯一性
- javascript - React / Nextjs 页面作为另一个页面上的 iframe 并调整大小