5

我从 Jenkins REST API 获得了原始 xml 数据http://jenkins-host:8080/api/xml。现在我正在努力从这个 xml 中获取作业名称列表到 perl 数组或变量中。以下是xml API的格式

<hudson>
<job>
  <name>Test_Job1</name>
  <url>http://jenkins-host:8080/job/Test_job1/</url>
  <color>red</color>
</job>
<job>
  <name>Test_job2</name>
  <url>http://jenkins-host:8080/job/Test_job2/</url>
  <color>red</color>
</job>
<view>
  <name>Test_View</name>
  <url>http://jenkins-host:8080/</url>
</view>
</hudson>

在这里,我只想将作业名称存储到数组中,而不是视图名称。前任:

@list = (Test_job1, Test_job2)
4

3 回答 3

2

使用 XML::Twig 将是:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my @jobs;
XML::Twig->new( twig_roots => { 'job/name' => sub { push @jobs, $_->text; } })
         ->parseurl( 'http://jenkins-host:8080/api/xml');
于 2012-12-27T20:10:59.617 回答
2
my $xml = <<XML;
<hudson>
<job>
  <name>Test_Job1</name>
  <url>http://jenkins-host:8080/job/Test_job1/</url>
  <color>red</color>
</job>
<job>
  <name>Test_job2</name>
  <url>http://jenkins-host:8080/job/Test_job2/</url>
  <color>red</color>
</job>
<view>
  <name>Test_View</name>
  <url>http://jenkins-host:8080/</url>
</view>
</hudson>
XML

my @rules = (
  'hudson' => sub { $_[1]->{name} },
  job  => sub { '@name' => $_[1]{name} },
  name => 'content',
  _default => undef,
);
my $xr = XML::Rules->new(rules => \@rules);
my $data = $xr->parse($xml);

print Dumper $data;

或者:

my @jobs;
my @rules = (
  job  => sub { push @jobs, $_[1]{name} },
  name => 'content',
  _default => undef,
);
my $xr = XML::Rules->new(rules => \@rules);
$xr->parse($xml);

print Dumper \@jobs;
于 2012-12-27T20:39:08.400 回答
1

最简单的事情就是这个正则表达式。

my @matches = ( $xml =~ m(<name>(.*?)</name>)gs) ;

如果您的 XML 格式经常更改,那么您将需要考虑使用 XML 解析器而不是这种简单的正则表达式匹配。


编辑:添加解释

正则表达式假定您在一个标量变量中拥有所有 XML,'s' 修饰符告诉 Perl 将整个字符串视为一个长行('.' 将匹配换行符),而 'g' 修饰符告诉 Perl搜索整个字符串,而不是在第一次匹配时退出。

正则表达式本身只是查找所有名称标签对,并捕获它们之间的内容。通过添加问号来修改'。' 模式,我们告诉 perl 是非贪婪的,所以当它看到第一个结束名称标签时停止捕获。除此以外 '。' 会匹配到最后一个结束标签,这不是我们想要的。

我们也可以将捕获写为 ([^<]+)。我想这是一个偏好问题。

于 2012-12-27T18:11:30.573 回答